I have a JS code and I am trying to make a button delete its parent element, it works, I could remove the second element then the first, but when I remove the first one, I can no longer delete the second one, it returns "btn[i] undefined".
let btn = document.getElementsByClassName('remove');
let div = document.getElementsByClassName('image');
//console.log(btn.length);
for (let i = 0; i < btn.length; i++) {
btn[i].onclick = function() {
btn[i].parentElement.remove();
}
}
<div class="image">
<img alt="First">
<button class="remove">X</button>
</div>
<div class="image">
<img alt="Second">
<button class="remove">X</button>
</div>
>Solution :
getElementsByClassName returns an HTMLCollection which updates dynamically as the DOM changes. This means, when you remove a button that was matched by your query selector, the collection updates dynamically and the array indices of each element change.
You start with two buttons with indexes 0 and 1. When you remove the 0th element, all subsequent elements "shift down" and occupy the space you just freed up. This means the button that was at btn[1] is now at btn[0], and when you attempt to run btn[1].parentElement..., you’re access outside the bounds of the collection
In order for your code to work, you need to access the element that was clicked, not the original array of btn elements:
let btn = document.getElementsByClassName('remove');
let div = document.getElementsByClassName('image');
//console.log(btn.length);
for (let i = 0; i < btn.length; i++) {
btn[i].onclick = function(event) {
event.target.parentElement.remove();
}
}
<div class="image">
<img alt="First">
<button class="remove">X</button>
</div>
<div class="image">
<img alt="Second">
<button class="remove">X</button>
</div>