Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Recursively remove all nested nodes in javascript

I've been trying to write something to remove all nodes within an element, including the nodes within those nodes. I feel like I've come pretty close with this

function clear(node) {
    var l = node.childNodes.length;
    for (var i = 0; i < l; i++) {
        console.log(i, node.childNodes);
        var child = node.childNodes[i];

        if (!child.hasChildNodes()) {
            var newchild = child.parentNode;
            newchild.removeChild(child);
            console.log("removed" + child);
            clear(newchild);
        } else {
            clear(child);
        }
    }
}

And the markup looks something like this

<div>
    <canvas></canvas>
    <div id="diagbox">
        <div id="diag_text">Here's some text</div>
    </div>
    <ul id="option_ul">
        <li>Some text</li>
        <li>Some text</li>
    </ul>
</div>

And this is how far it gets before failing:

<div>
    <div id="diagbox">
        <div id="diag_text"></div>
    </div>
    <ul id="option_ul">
    </ul>
</div>

It removes the text node in diag_text, but fails to remove the actual div. It also removes the text nodes in the li elements, and for some reason succeeds to remove the li elements as well, but stops at the ul. The canvas is also succesfully removed, which is odd because it's top level and I was assuming that's why the others weren't working. The whole thing stops because at some point a TypeError occurs, "child is undefined".

Not quite sure where I'm going wrong here

EDIT: Definitely should have specified: I'm wanting to go through and remove all of the nodes and not just the parents because the content of these elements are actually dynamically generated and need to be scrubbed for different use cases.

like image 505
lyon Avatar asked Dec 24 '22 15:12

lyon


1 Answers

I think the recursive solution may be a lot simpler than you had in mind.

This function will delete each node only after all of its child nodes have been deleted, so you can scrub/free any resources you need to reclaim.

Working Live Example (open console):

var n = document.getElementById("parent");

function clearInner(node) {
  while (node.hasChildNodes()) {
    clear(node.firstChild);
  }
}

function clear(node) {
  while (node.hasChildNodes()) {
    clear(node.firstChild);
  }
  node.parentNode.removeChild(node);
  console.log(node, "cleared!");
}

clearInner(n);
<div id="parent">
  <div></div>
  <div></div>
  <div>
    <div></div>
    <div></div>
    <div>
      <div></div>
      <div></div>
    </div>
  </div>
  <div></div>
  <div></div>
</div>
like image 142
Maximillian Laumeister Avatar answered Dec 28 '22 14:12

Maximillian Laumeister