innerHTML only takes effect once, and dynamically generated elements

1

I'm doing a javascript experiment that when clicking on a certain element with a certain class we will add a new element with the same class, whenever a new element should be clicked.

var my_divs = document.getElementsByClassName('my-div');
for (var i = 0; i < my_divs.length; i++) {
    my_divs[i].addEventListener('click', function() {
       var next_id = my_divs.length + 1; 
       document.body.innerHTML += '<div id="div' +next_id+ '" class="my-div"></div>';
       //console.log(next_id);
    });
}
.my-div {
  width:20px;
  height:20px;
}
.my-div:nth-child(odd) {
  background-color:red;
}
.my-div:nth-child(even) {
  background-color:blue;
}
<div id="div1" class="my-div">

</div>

As you can see, it works, but only once. I even understand that clicking the one that appears dynamically does nothing because the event did not get associated with the new div. But anyway, why does the click on the first only work once? And how would you do to get what I want? Whenever I click on any ( .my_div ), dynamically generated or not another appears?

    
asked by anonymous 30.05.2016 / 11:35

1 answer

1

The problem is that += is the same as document.body.innerHTML = document.body.innerHTML + resto , that is re-writes all HTML and therefore breaks the event headphones.

To make this work for any element (created after or not) you need a delegator, in which case you can use .appendChild() or re-write the whole HTML as you were doing. I prefer to use .appendChild() , using += in body.innerHTML is violent and can ruin code in other parts of the DOM.

Example using delegation:

var ids = 2;
var minhaClasse = 'my-div';
window.addEventListener('click', function(e) {
    var el = e.target;
    if (!el.classList.contains(minhaClasse)) return;
    var div = document.createElement('div');
    div.classList.add(minhaClasse);
	div.id = ids++;
    document.body.appendChild(div);
});
.my-div {
    margin: 20px;
    height: 20px;
    width: 20px;
    background-color: #ddf;
}
<div id="div1" class="my-div"></div>

jsFiddle: link

Another more local way would look like this:

function addDiv() {
    var div = document.createElement('div');
    div.classList.add(minhaClasse);
    div.id = ids++;
    div.addEventListener('click', addDiv);
    document.body.appendChild(div);
}
document.querySelector('.my-div').addEventListener('click', addDiv);

jsFiddle: link

    
30.05.2016 / 11:46