Skip to content
Advertisement

Only the last element I added using innerHTML keeps its event handlers, why?

I am trying to make a script that injects interactable object information in a list of the markup page. Whenever I try to add an onclick event on a div, it works fine, however whenever I try to add more within a for loop, it does not work the way I intended.

I took a look of what is going on using breakpoints in the webpage debugger, and I see that the problem is that it seems to delete the event on the previous div before adding to the next div. In the end, the only event remaining is the last div after the loop exits.

I want to keep these events on all my divs, not just the last one… what seems to be the problem here?

var objects = ['Tom', 'Sauna', 'Traum'];

for (var i = 0; i < objects.length; i++){
    document.getElementById('list').innerHTML += "<div class='item' id='"+ i +"'>" + objects[i] + "</div>";
    document.getElementById(i).addEventListener("mouseup", function() {
        Select(this);
    });
}

function Select(char) {
    console.log(char);
}
div.item {
    border: 1px solid black;
    padding: 4px;
    margin: 4px;
}
<div id="list"></div>

enter image description here

Advertisement

Answer

When you change innerHTML browser reconstructs the element’s contents, throwing away all event handlers attached. Use DOM methods instead:

    for (let i = 0; i < objects.length; i++){
        var block = document.createElement('div');
        block.setAttribute('id', i);
        document.getElementById('list').appendChild( block );
        block.addEventListener("mouseup", function() {
            Select(this);
        });
    }

UPD: alternatively use a insertAdjacentHTML method instead of redefining innerHTML:

document.getElementById('list').insertAdjacentHTML(
    'beforeend', "<div id='"+ i +"'>" + i + "</div>");
User contributions licensed under: CC BY-SA
10 People found this is helpful
Advertisement