ajax перезагружает ul / li div и сохраняет прослушиватели событий (кроме insertAdjacentHTML) - PullRequest
1 голос
/ 27 апреля 2019

Цель : перезагрузить только div после ajax-вызовов (добавить или удалить теги) без потери прослушивателей событий в перезагруженном div.Использование insertAdjacentHTML не кажется оптимальным.

Front-end : у меня есть боковая панель с тегами ul / li.Есть модал для добавления / создания тегов;рядом с каждым тегом стоит значок "X", чтобы удалить его при нажатии.

<ul>
  <li><span>A</span><span class=li-untag>X</span> 
  <li><span>B</span><span class=li-untag>X</span> 
  <li><span>C</span><span class=li-untag>X</span> 
  <li><span>D</span><span class=li-untag>X</span>
</ul>

Моя неудачная установка была :

  1. отправитьajax (выборочный) вызов в php-сервер для добавления или удаления тегов

  2. , если нет ошибок, сервер отправляет обновленный и отформатированный в виде веточки список тегов для статьи.

  3. обновил div с помощью innerHTML.

Обновление innerHTML потеряло бы все прослушиватели событий в списке (такие как удаление тега при нажатии X) дореальное обновление страницы.Я попытался запустить addeventlisteners после вызова ajax, но он не сработал.

Моя текущая настройка на основе предыдущих ответов SO (см. Ниже) использует insertAdjacentHTML.Это (вроде) работает, но неуклюже.

1 Ответ

1 голос
/ 27 апреля 2019

Лучшим решением для чего-то подобного было бы использование делегирования события для присоединения одного слушателя к ul вместо подключения нескольких слушателей к каждому li-untag:

document.querySelector('ul').addEventListener('click', ({ target }) => {
  if (target.matches('.li-untag')) {
    target.closest('li').remove();
  }
});

Если вы не хотите этого делать и хотите сохранить прослушиватель для каждого элемента li-untag, вы можете вставить новый HTML-код, затем отсортировать <li> s и прикрепить прослушиватели к каждому новому li-untag:

const addListeners = () => {
  document.querySelectorAll('.li-untag').forEach((span) => {
    span.addEventListener('click', ({ target }) => {
      target.closest('ul').remove();
    });
  });
};

// on document load:
addListeners();

// after inserting new HTML:
const lis = [...document.querySelectorAll('ul li')];
lis.sort((a, b) => a.children[0].textContent.localeCompare(b.children[0].textContent));
const ul = document.querySelector('ul');
lis.forEach((li) => {
  ul.appendChild(li);
});
addListeners();
...