javascriptloopsfor-loopiterationchild-nodes

JS: Deleting multiple child nodes with for-loop?


I'd like to execute a function that iterates over the child nodes of an element and subsequently deletes each child node.

In my current setup, for some reason, only some of the child nodes get deleted, some don't. The function needs to run multiple times to delete all nodes. Why aren't all nodes deleted at once?

Here's a simplified version of the code:

const deleteBtn = document.getElementById("deleteBtn");
const sidebar = document.getElementById("sidebar");

deleteBtn.addEventListener("click", () => {
  const links = sidebar.children;
  console.log(links)

  for (let i = 0; i < links.length; i++) {
    const link = links[i];
    link.remove()
  }
})
.sidebar__link-group {
  display: flex;
  flex-direction: column;
}
<button id="deleteBtn" >Click to delete all links</button>

<div id="sidebar" class="sidebar__link-group">
  <a class="sidebar__link" href="#">Some link</a>
  <a class="sidebar__link" href="#">Some link</a>
  <a class="sidebar__link" href="#">Some link</a>
  <a class="sidebar__link" href="#">Some link</a>
  <a class="sidebar__link" href="#">Some link</a>
  <a class="sidebar__link" href="#">Some link</a>
</div>


Solution

  • When you remove the 0th element, the 1st element becomes the 0th, the 2nd element becomes the 1st, etc, so after your first i++, you're gonna delete the "original 2nd" element, and so on; that is why your algorithm only removes every other children instead of every children.

    That's typically the kind of algorithm where you'd want to use a while instead of an array iteration:

    const deleteBtn = document.getElementById("deleteBtn");
    const sidebar = document.getElementById("sidebar");
    
    deleteBtn.addEventListener("click", () => {
      while(sidebar.children.length > 0) {
        sidebar.children[0].remove();
      }
      console.log('done');
    })
    .sidebar__link-group {
      display: flex;
      flex-direction: column;
    }
    <button id="deleteBtn" >Click to delete all links</button>
    
    <div id="sidebar" class="sidebar__link-group">
      <a class="sidebar__link" href="#">Some link</a>
      <a class="sidebar__link" href="#">Some link</a>
      <a class="sidebar__link" href="#">Some link</a>
      <a class="sidebar__link" href="#">Some link</a>
      <a class="sidebar__link" href="#">Some link</a>
      <a class="sidebar__link" href="#">Some link</a>
    </div>