Как в JavaScript обновить список элементов, полученных с помощью `querySelectorAll`, и их обработчики событий после удаления одного из элементов?

Добрый день! <br/> У меня есть простая корзина, в которой элементы удаляются с помощью jQuery. <br/> <pre><code class="javascript">$('.show-cart').on("click", ".delete-item", function (event) {
    var name = $(this).data('name')
    shoppingCart.removeItemFromCartAll(name);
    displayCart();
  })</code></pre> <br/> <br/> Как можно переписать этот код на чистом JavaScript? Я пробую следующее: <br/> <pre><code class="javascript">const deleteItemBtn = document.querySelectorAll('.delete-item');
  
  deleteItemBtn.forEach((item)=&gt;{
      item.addEventListener('click', ()=&gt;{
          const name = item.dataset.name
          shoppingCart.removeItemFromCartAll(name);
          displayCart();
  })
})</code></pre> <br/> Однако, этот код работает только один раз. <br/> Как обновить данные о новых элементах при каждом срабатывании addEventListener?
  • 19 октября 2024 г. 8:02
Ответы на вопрос 2
Ваша проблема заключается в том, что вы собираете элементы с помощью `querySelectorAll` только один раз, и после удаления элемента из DOM список `deleteItemBtn` больше не соответствует текущему состоянию DOM. После удаления элемента вам нужно заново получать элементы и добавлять слушатели событий.

Вот как можно переписать ваш код, чтобы он работал правильно с обновленным списком элементов:

```javascript
const showCartButton = document.querySelector('.show-cart');

// Функция для обновления обработчиков событий
function updateDeleteButtons() {
    const deleteItemBtns = document.querySelectorAll('.delete-item');
    
    deleteItemBtns.forEach(item => {
        // Снимаем старые обработчики, если они были добавлены ранее
        item.replaceWith(item.cloneNode(true)); // Создает новый элемент с теми же свойствами (в т.ч. data атрибутами)

        item.addEventListener('click', () => {
            const name = item.dataset.name;
            shoppingCart.removeItemFromCartAll(name);
            displayCart();
            updateDeleteButtons(); // Обновляем обработчики после изменения корзины
        });
    });
}

// Инициализация обработчиков событий при загрузке страницы
updateDeleteButtons();

// Кроме того, вы также можете добавить обработчик на кнопки показа корзины,
// если они динамически создаются (например, открытие корзины)
showCartButton.addEventListener('click', displayCart);
```

В этом коде мы создали функцию `updateDeleteButtons`, которая находит все текущие элементы с классом `delete-item` и устанавливает для них слушатели событий. После вызова `removeItemFromCartAll`, мы снова вызываем `updateDeleteButtons`, чтобы обновить слушатели событий для оставшихся элементов. 

Кроме того, `item.replaceWith(item.cloneNode(true))` позволяет удалить старый обработчик событий на старом элементе, при этом сохраняя все необходимые атрибуты (включая `data-name`), и добавляя новый обработчик на новый элемент.

Этот подход позволяет вам динамически обновлять обработчики событий для элементов в корзине при каждом изменении.
слушайте событие клика как jQuery – не на каждой кнопке по отдельности, а один раз на общем родителе: на этом .show-cart 

В обработчике проверяйте, по чему именн, там, где-то в дочерних, кликнули (см. event.target ). Если у кликнутого есть класс .delete-item , то действуем далее.

Слушать на общем родителе – называется волшебным термином «делегирование событий».
Похожие вопросы