Any change to the innerHTML property results in a complete replacement of all elements.
So after doing
document.body.innerHTML += 'Next line';
the div element to which the handler has been added has been removed, and now a new div is instead replaced by the handler.
To solve, you can either collect the entire line at once, and only then hang handlers
var div = `<div id="div">Default message</div>`; document.body.innerHTML += div; document.body.innerHTML += 'Next line'; document.getElementById('div').onclick = function() { this.innerHTML = 'Onclick message' }
or do not use innerHTML , but create elements directly:
var div = document.createElement('div'); div.innerHTML = "Default message"; div.onclick = function() { this.innerHTML = 'Onclick message' } document.body.appendChild(div); var textNode = document.createTextNode('Next line'); document.body.appendChild(textNode);
An alternative way to add markup, as suggested in the comments , is to use the insertAdjacentHTML method.
var div = document.createElement('div'); div.innerHTML = "Default message"; div.onclick = function() { this.innerHTML = 'Onclick message' } document.body.appendChild(div); div.insertAdjacentHTML('afterEnd', 'Next line');