I recently wanted to remove certain elements on my page. They all shared the same class, but I ran into problems when the last one in the list was not removed. This was due to the way I tried to remove them using a "for" loop. The issue boils down to removing items from a list while iterating through it - a classic mistake. My HTML looked like the following:
<section class="post-content">
<aside class="sidebar left-sidebar">
<div class="lazy-load-ad sidebar-ad">
</div>
</aside>
<!-- My post content is here -->
<aside class="sidebar right-sidebar">
<div class="lazy-load-ad sidebar-ad">
</div>
</aside>
</section>
The elements that I wanted to remove were the ads in the sidebars of my page. If the users screen is too small there is no space for them and therefore there was no reason to load them. My first attempt looked like the following:
var sidebarAds = document.getElementsByClassName("sidebar-ad");
for (var i = 0; i < sidebarAds.length; i++) {
var sidebarAd = sidebarAds[i];
sidebarAd.parentNode.removeChild(sidebarAd);
}
I selected the elements using the "getElementsByClassName" function and then iterated through them and deleted them one by one. The problem was that, as I deleted the items they were removed from the HTMLCollection
. As there were two "siderbar-ad" elements the second would never be deleted, the list would never enter the second loop as there would only be 1 item in the list when the first is removed, so the length of the array would be 1 and the loop would stop and never do a second iteration. Leaving me without any error in the console and without all the elements being removed from the page.
So what do you do when a list is slowly emptied and items are removed with each iteration? You just keep deleting the first item until none are left. So instead of using a "for" loop I introduced a "while" loop and kept deleting the first item until all were gone:
var sidebarAds = document.getElementsByClassName("sidebar-ad");
while (sidebarAds.length > 0) {
var sidebarAd = sidebarAds[0];
sidebarAd.parentNode.removeChild(sidebarAd);
}
That is it, instead of iterating through the list I just kept on deleting the first item until none were left. If you found this useful, please leave a comment down below!