addEventListener становится игнорируемым - PullRequest
1 голос
/ 04 октября 2019

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

for (var i = 0; cities.length > i; i++) {
        if (cities[i].toLowerCase().indexOf(value.toLowerCase()) !== -1 && citiesList <= 10) {
            citiesList ++;
            dropdown.classList.add('show');
            dropdown.innerHTML += '<a class="dropdown-item" id="dropdown_item-' + i + '" href="#">' + cities[i] + '</a>';
            var item = document.getElementById('dropdown_item-' + i);
            item.addEventListener("click", function(){ console.log("test") });
            console.log(item);
        }
    }

Но когда я нажимаю на элементы, событие не срабатывает, даже если console.log правильно регистрирует элемент и когда я вручную добавляю прослушиватель через консольоно работает. Я попытался использовать функцию тайм-аута, но без преобладания.

1 Ответ

2 голосов
/ 04 октября 2019

Когда вы += используете innerHTML контейнера, содержимое контейнера полностью пересматривается только из их HTML-разметки. Все остальное (например, прослушиватели событий, отсутствующие в разметке HTML) будет потеряно. Вместо этого используйте insertAdjacentHTML:

Метод insertAdjacentHTML () интерфейса Element анализирует указанный текст как HTML или XML и вставляет результирующие узлы в дерево DOM по указанномупозиция. Он не обрабатывает элемент, на котором он используется, и, таким образом, он не разрушает существующие элементы внутри этого элемента. Это позволяет избежать дополнительного шага сериализации, делая его намного быстрее, чем прямое манипулирование внутренним HTML.

dropdown.insertAdjacentHTML('beforeend', '<a class="dropdown-item" id="dropdown_item-' + i + '" href="#">' + cities[i] + '</a>');

Тем не менее, похоже, что вы, возможно, присваивает элементу идентификатор только для того, чтобы вы могли выбрать егои впоследствии присоедините слушателя к этому. Динамические идентификаторы - довольно плохая идея - если причина для идентификатора, было бы лучше создать элемент, используя вместо этого createElement:

const a = document.createElement('a');
a.className = "dropdown-item";
a.textContent = cities[i];
a.addEventListener("click", function() {
  console.log("test")
});
dropdown.appendChild(a);

Имейте в виду, что i будет равен cities.length после окончания цикла, учитывая ваш текущий код. Если вы ссылаетесь на i внутри обратного вызова слушателя, если вы хотите, чтобы он ссылался на i, используемый для этой конкретной итерации, вам нужно вместо этого использовать i в области: измените

for (var i = 0; cities.length > i; i++) {

на

for (let i = 0; cities.length > i; i++) {

(или, что еще лучше, используйте Array.prototype.forEach или что-то в этом роде вместо того, чтобы вручную связываться с указателями)

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