Манипуляция innerHTML удаляет обработчик события дочернего элемента?

У меня есть эта простая демонстрация:

function foo() {
    alert('Works!');
}

var inp = document.createElement('input');
inp.onblur = foo;
document.body.appendChild(inp);

Смотрите здесь: http://jsfiddle.net/A7aPA/

Как вы можете видеть, это работает. (Нажмите на вход, затем щелкните в другом месте и появится предупреждение.)

Однако, если я добавлю эту строку в код JavaScript:

document.body.innerHTML += '<br>'; 

тогда обработчик размытия перестает работать (и ошибка не возникает из-за ошибки).

См. здесь: http://jsfiddle.net/A7aPA/1/

Почему это?

Ответы

Ответ 1

Да, когда вы выполните:

document.body.innerHTML += '<br>'; 

Вы действительно делаете:

document.body.innerHTML = (document.body.innerHTML + '<br>'); 

Итак, вы полностью уничтожаете и воссоздаете весь контент.

Ответ 2

Изменение innerHTML приводит к повторному анализу содержимого и воссозданию узлов DOM, потере обработчиков, которые вы подключили. Добавление элементов, как в первом примере, не вызывает такого поведения, поэтому повторный анализ не должен происходить, поскольку вы явно изменяете дерево DOM.

Еще один хороший способ справиться с этим - использовать insertAdjacentHTML(). Например:

document.body.insertAdjacentHTML('beforeend', '<br>')