首页 > 解决方案 > 为什么循环遍历所有 div 的孩子 + 删除它们仅在 X 使用后才开始工作?

问题描述

为什么此代码在第一次使用后没有删除所有节点,但在 2 或 3 次之后却删除了?

function remove()
{
    var nodes = document.getElementById("test").childNodes;

    for (var i=0; i<nodes.length; i++)
    {
      nodes[i].parentNode.removeChild(nodes[i]);
    }
}

使用按钮几次:

https://jsfiddle.net/ekbadocs/

标签: javascriptfrontend

解决方案


因为你在删除时忘记了一些节点

第一次通话

var nodes = document.getElementById("test").childNodes;
console.log(nodes)// NodeList(5) [ #text, div.red, #text, div.green, #text ]

// here's what append in for loop
// i | nodes[i]  | nodes
// 0 | #text     | #text, div.red, #text, div.green, #text
// 1 | #text     | div.red, #text, div.green, #text
// 2 | #text     | div.red, div.green, #text
// 3 | undefined | div.red, div.green
// 4 | undefined | div.red, div.green
for (var i=0; i<nodes.length; i++)
{
    nodes[i].parentNode.removeChild(nodes[i]);
}

第二次通话

var nodes = document.getElementById("test").childNodes;
console.log(nodes)// NodeList(5) [ div.red, div.green ]

// here's what append in for loop
// i | nodes[i]  | nodes
// 0 | div.red   | div.red, div.green
// 1 | undefined | div.green
for (var i=0; i<nodes.length; i++)
{
    nodes[i].parentNode.removeChild(nodes[i]);
}

第三次通话

var nodes = document.getElementById("test").childNodes;
console.log(nodes)// NodeList(5) [ div.green ]

// here's what append in for loop
// i | nodes[i]  | nodes
// 0 | div.green | div.green
for (var i=0; i<nodes.length; i++)
{
    nodes[i].parentNode.removeChild(nodes[i]);
}

所以它每次只删除列表中奇数索引上的节点,因为当您的列表更改时循环向前移动一个并且其中的值“向后移动一个索引”填充被清空的位置


采用

let last; while (last = node.lastChild) node.removeChild(last);

要删除节点的每个子节点,它会向后退以防止出现此问题

或保持您的逻辑,仅删除第一个值,因为该元素在每次迭代时都是向后的一个索引

for (var i=0; i<nodes.length; i++)
{
    nodes[0].parentNode.removeChild(nodes[0]);
}

推荐阅读