Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Manipulating innerHTML removes the event handler of a child element? [duplicate]

I have this very simple demo:

function foo() {     alert('Works!'); }  var inp = document.createElement('input'); inp.onblur = foo; document.body.appendChild(inp); 

See here: http://jsfiddle.net/A7aPA/

As you can see, this works. (Click on the input, then click somewhere else and an alert will pop up.)

However, if I add this line to the JavaScript code:

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

then the blur handler stops working (and no error is thrown btw).

See here: http://jsfiddle.net/A7aPA/1/

Why is that?

like image 909
Šime Vidas Avatar asked Feb 25 '11 02:02

Šime Vidas


People also ask

Does innerHTML remove event listeners?

'innerHTML' Removes Event Listeners Since the entire tag (the div in our code) is being reparsed, the event listener is lost in the process. Rather than using the += operator, use DOM functions such as append() .

What does innerHTML do?

The innerHTML property is part of the Document Object Model (DOM) that allows Javascript code to manipulate a website being displayed. Specifically, it allows reading and replacing everything within a given DOM element (HTML tag).

Why innerHTML does not work?

People can struggle and complain about innerHTML not working. Such things usually occur because of human error, when strings are not appropriately defined, or there are some mistakes in JavaScript code.


2 Answers

Yes, when you do:

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

You're really doing:

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

So you're completely destroying and recreating all the content.

like image 66
user113716 Avatar answered Oct 26 '22 21:10

user113716


Modifying innerHTML causes the content to be re-parsed and DOM nodes to be recreated, losing the handlers you have attached. Appending elements as in the first example doesn't cause that behavior, so no re-parsing has to occur, since you are modify the DOM tree explicitly.

Another good way to handle this is to use insertAdjacentHTML(). For example:

document.body.insertAdjacentHTML('beforeend', '<br>') 
like image 32
ctcherry Avatar answered Oct 26 '22 22:10

ctcherry