Каждый раз, когда вы присваиваете innerHTML
контейнера, любые ссылки Javascript на элементы внутри контейнера уничтожаются.Когда вы делаете something.innerHTML +=
, интерпретатор делает что-то вроде:
(1) Извлекает текущий innerHTML
контейнера в виде строки
(2) Очищает содержимое контейнера
(3) Объединяет строку с тем, что вы добавили
(4) Присваивает внутреннему HTML контейнера новую строку
Так что если у вас есть элемент внутри контейнера, и вы назначаете егослушатель события, если вы когда-либо назначите (или объедините) контейнер innerHTML
, слушатель будет потерян;вся внутренняя структура контейнера будет заново проанализирована с HTML-строки.
Существует как минимум два хороших решения для такого рода вещей:
- Недобавлять строки HTML, особенно когда имеешь дело с пользовательским вводом.Вместо этого создайте элементы и добавьте их в контейнер:
const text = document.querySelector('#text');
const wordsGeneral = ['foo', 'bar', 'baz'];
for (let i = 0; i < wordsGeneral.length; i++) {
const word = wordsGeneral[i];
text.insertAdjacentHTML('beforeend', "<u id=\"" + i + "\" style=\"text-decoration: underline;text-decoration-color: red;\">" + word + "</u>");
document.getElementById(i).addEventListener("click", function() {
alert("2");
});
}
<div id="text"></div>
Другой метод заключается в использовании метода appendAdjacentHTML
, который предназначен для такого рода вещей и не разыменовывает другие элементы в контейнере:
const text = document.querySelector('#text');
const wordsGeneral = ['foo', 'bar', 'baz'];
for (let i = 0; i < wordsGeneral.length; i++) {
var word = wordsGeneral[i];
const u = text.appendChild(document.createElement('u'));
u.id = i;
u.style.cssText = 'text-decoration: underline;text-decoration-color: red;';
u.textContent = word;
u.addEventListener("click", function() {
alert("2");
});
}
<div id="text"></div>