Удалить объект из массива при нажатии - PullRequest
0 голосов
/ 14 июля 2020

Мне нужна помощь с удалением объекта из массива.

Имена (array.name) объектов отображаются в DOM, и я хочу удалить их с помощью кнопки стирания X.

В этом коде я могу удалить только один элемент, а затем перестает работать без ошибки консоли. Есть ли у кого-нибудь идеи, где я ошибаюсь и почему я не могу вызывать функцию create () каждый раз, когда нажимаю кнопку стирания.

Посмотрите console.log ... он показывает хорошее положение и имя удаляемого элемента, но все останавливается, когда я вызываю функцию create (), попробуйте раскомментировать create ().

const array = [ {name: 'John'}, {name: 'David'}, {name: 'Peter'}, {name: 'Michael'} ]; 

const create = () => {
    const app = document.querySelector('.app');
    app.innerHTML = '';

    for(let i = 0; i < array.length; i++) {
      app.innerHTML += `<div class="item"><span class="erase">&#9747;</span>${array[i].name}</div>`;
    }
}
create();

const erase = document.querySelectorAll('.erase');

erase.forEach(item => {
    item.onclick = () => {
      const itemText = item.parentElement.textContent.substr(1);
      const itemPos = array.findIndex(item => item.name == itemText);
    
        console.log(itemText + ' ' + itemPos);
        console.log(array);
        array.splice(itemPos, 1);
        //create()
    }
});
.erase {
  color: red;
  margin-right: 20px;
  cursor: pointer;
}

.item {
  margin-bottom: 10px;
}
<div class="app"></div>

Или как скрипка: https://jsfiddle.net/05cwy9d2/3/

Ответы [ 6 ]

3 голосов
/ 14 июля 2020

Это потому, что когда вы создаете новые элементы в dom, слушатели старых элементов удаляются вместе со старыми элементами. Просто переместите регистрацию прослушивателя событий в метод create.

const array = [
  {name: 'John'},
  {name: 'David'},
  {name: 'Peter'},
  {name: 'Michael'}
]; 

const create = () => {
  const app = document.querySelector('.app');
  app.innerHTML = '';

  for(let i=0;i<array.length;i++){
    app.innerHTML += 
      `<div class="item"><span class="erase">&#9747;</span>${array[i].name}</div>`;
  }

  const erase = document.querySelectorAll('.erase');

  erase.forEach(item => {
    item.onclick = () => {
      const itemText = item.parentElement.textContent.substr(1);
      const itemPos = array.findIndex(item => item.name == itemText);


      console.log(itemText + ' ' + itemPos);
      console.log(array);
      array.splice(itemPos, 1);
      create();
    }
  });
}

create();
.erase{
color: red;
margin-right: 20px;
cursor: pointer;
}
.item{
margin-bottom: 10px;
}
<div class="app"></div>
1 голос
/ 14 июля 2020
const array = [
  {name: 'John'},
  {name: 'David'},
  {name: 'Peter'},
  {name: 'Michael'}
]; 

const create = () => {
    const app = document.querySelector('.app');
    app.innerHTML = '';

    for(let i=0;i<array.length;i++){
      app.innerHTML += 
      `<div class="item"><span class="erase">&#9747;</span>${array[i].name}</div>`;
    }
}
create();

const erase = document.querySelectorAll('.erase');

erase.forEach(item => {

    item.onclick = () => {
      const itemText = item.parentElement.textContent.substr(1);
      const itemPos = array.findIndex(item => item.name == itemText);
    
        console.log(itemText + ' ' + itemPos);
        
        if(itemPos >-1){
            array.splice(itemPos, 1);
            item.parentElement.remove();
        }
        console.log(array);
    }
});

Теперь это работает. Я удалил DOM при нажатии на стирание и отключил пользователя, чтобы удалить элемент, который уже был удален (если index == -1).

0 голосов
/ 14 июля 2020

вместо повторного вызова функции create () и создания новых дочерних элементов для класса '.app' вы должны использовать item.parentElement.remove (); вместо create () в onClick. Результат будет тот же.

erase.forEach (item => {

item.onclick = () => {
 console.log()
  const itemText = item.parentElement.textContent.substr(1);
  const itemPos = array.findIndex(item => item.name == itemText);

    console.log(itemText + ' ' + itemPos);
    console.log(array);
    array.splice(itemPos, 1);
   item.parentElement.remove(); // this will remove your element.
  // create();
  
}

});

0 голосов
/ 14 июля 2020

Вы можете использовать метод removeChild для удаления элемента из вашей DOM, этот способ предотвратит повторную визуализацию (с помощью метода create ) каждый раз, когда вы удаляете элемент из массива. Таким образом, ваш код потребует некоторых изменений, первое из них - иметь идентификатор для каждого элемента вашего массива:

for(let person of array){
  app.innerHTML += 
  `<div class="item" id="${person.name}"><span class="erase">&#9747;</span>${person.name}</div>`;
}

После использования имени «человека» в качестве идентификатора (я рекомендую вам иметь реальный идентификатор, например число, но в этом примере имя нам поможет), вы можете удалить только этот узел из DOM:

const elementToRemove = document.getElementById(item.parentElement.id);
elementToRemove.parentNode.removeChild(elementToRemove);

Для улучшения вы можете проверить, существует ли узел, и в противном случае вы можете выдать ошибку на свою консоль:

const elementToRemove = document.getElementById(item.parentElement.id);

if (!elementToRemove) throw new Error(`Element ${item.parentElement.id} not found!`)

elementToRemove.parentNode.removeChild(elementToRemove)

Я рекомендую вам прочитать раздел Node на MDN , это может быть полезно для добавления других элементов в список, отредактируйте некоторые элементы и многое другое. :)

0 голосов
/ 14 июля 2020

Я переместил код прослушивателя событий в функцию create, потому что необходимо воссоздать его при возникновении одного события. Вы также можете использовать метод EventTarget.addEventListener () для привязки прослушивателей событий к каждому отдельному элементу DOM.

Я бы также предпочел использовать Array.prototype.filter () метод удаления значения щелчка для лучшей читаемости:

let array = [
  {name: 'John'},
  {name: 'David'},
  {name: 'Peter'},
  {name: 'Michael'}
]; 

const addEventListeners = () => {
  const erase = document.querySelectorAll('.erase');
  erase.forEach(item => {
    item.onclick = (e) => {
        const itemText = item.parentElement.textContent.substr(1);
        array = array.filter(entry => entry.name !== itemText);
        create();
    }
  });
}

const create = () => {
    const app = document.querySelector('.app');
    app.innerHTML = '';

    for(let i=0;i<array.length;i++){
      app.innerHTML += 
      `<div class="item"><span class="erase">&#9747;</span>${array[i].name}</div>`;
    }
    addEventListeners();
}
create();
<div class="app"></div>
0 голосов
/ 14 июля 2020

Вам нужно просто удалить элемент dom

    e.target.parentNode.parentNode.removeChild(e.target.parentNode);

https://jsfiddle.net/tLk5vmy0/

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...