递归删除javascript中的所有嵌套节点

递归删除javascript中的所有嵌套节点,javascript,dom,recursion,Javascript,Dom,Recursion,我一直在尝试写一些东西来删除元素中的所有节点,包括这些节点中的节点。我觉得我已经接近这个目标了 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.hasCh

我一直在尝试写一些东西来删除元素中的所有节点,包括这些节点中的节点。我觉得我已经接近这个目标了

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);
        }
    }
}
功能清除(节点){
var l=node.childNodes.length;
对于(变量i=0;i
标记看起来像这样

<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>

这里有一些文字
  • 一些文本
  • 一些文本
这就是它在失败之前能走多远:

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

它删除diag_text中的文本节点,但无法删除实际div。它还删除li元素中的文本节点,出于某种原因也成功删除li元素,但在ul处停止。画布也被成功地移除了,这很奇怪,因为它是顶级的,我想这就是为什么其他人不工作的原因。整个过程之所以停止,是因为在某个时候发生了一个类型错误,“child未定义”

我不太确定我在这出了什么错


编辑:当然应该指定:我希望遍历并删除所有节点,而不仅仅是父节点,因为这些元素的内容实际上是动态生成的,需要针对不同的用例进行清理。

首先,您不需要删除子节点。移除父对象就可以了。因此,某种形式:

while (node.firstChild) {
  node.removeChild(node.firstChild)
}
我会成功的

至于你的具体问题:childNodes是动态的。当您删除元素时,它会发生更改,因此从静态长度索引到它将不起作用。您会注意到,在我上面的示例中,我只查看firstChild,因为在每个removeChild之后,它将指向一个新元素

因此,要修复代码,请使用如下动态方式或反向处理数组:

for (var i = l - 1; i >= 0; i--) {...

这将起作用,因为您正在从末尾截断节点,并且前面的子节点仍保留在原位。

我认为递归解决方案可能比您想象的要简单得多

此函数将仅在删除每个节点的所有子节点后删除每个节点,因此您可以清除/释放需要回收的任何资源

实时工作示例(开放控制台):

var n=document.getElementById(“父项”);
函数clearInner(节点){
while(node.hasChildNodes()){
清除(node.firstChild);
}
}
功能清除(节点){
while(node.hasChildNodes()){
清除(node.firstChild);
}
node.parentNode.removeChild(节点);
log(节点“已清除!”);
}
clearInner(n)

为什么不

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

n.innerHTML="";

你希望你的最终结果是什么?此外,在尝试对其进行操作之前,您应该检查以确保实际定义了
child
。还有,有没有什么原因可以让子节点删除而不是只删除父节点?是的,我想我应该指定,有一个原因我不只是删除父节点。这些元素是动态生成的,需要针对不同的用例进行清理。当您删除node.childNodes[i]时,代码中的问题是for循环,增加迭代器后,原来的node.childNodes[i+1]变为[i]并被跳过。提示-重复删除node.childNodes[0](或.firstChild)。关于发布的html,您想遗漏什么?抱歉!肯定应该指定:我希望遍历并删除所有节点,而不仅仅是父节点,因为这些元素的内容实际上是动态生成的,需要针对不同的用例进行清理。-我要试着反向遍历它,并在有机会再次使用firstChild时使用它,谢谢,我确实认为我把它复杂化了,您的解决方案非常接近我要寻找的,但唯一的问题是我需要父节点(在本例中,n)也不要删除