I am dynamically appending divs to a parent wrapper by looping through an array. After appending the inner div I attach an onclick event listener to each inner div that prints out the id of each innerDiv. Why is the below code only printing the id of the last appended innerDiv?
let arr = ['a', 'b', 'c']
const wrapper = document.querySelector('.wrapper')
for (var i = 0; i < arr.length; i++) {
wrapper.innerHTML += `<div class="container" id="${arr[i]}"></div>`
let container = document.querySelector(`#${arr[i]}`)
container.onclick = (e) => {
console.log(e.target.id)
}
}
.wrapper {
display: flex;
flex-direction: column;
row-gap: 15px;
width: 500px;
border: 2px solid #000;
}
.container {
width: 100%;
height: 80px;
cursor: pointer;
background-color: blue;
}
<div class="wrapper"></div>
2
Answers
When you add an element with this method (
+=
), after each loop it recreates all the elements inside the wrapper (when it concatenates the string and the innerHTML). This also means that the previously attached event listener (onclick
) is removed, since it is "not the same" element anymore.To prevent this, you can use a different method to add the new divs:
When you use
innerHTML += ...
, it indeed re-renders the entire content of the wrapper, and this process causes the loss of all previously attached events. The reason is that theinnerHTML
property sets or gets the HTML content within an element, and when you use the+=
operator, you are essentially overwriting the existing content with the new content, erasing any previously attached event listeners in the process.You can try try using
insertAdjacentHTML()
: