for ... in循环不循环遍历所有属性?

时间:2015-09-25 14:51:57

标签: javascript for-loop for-in-loop nodelist

当我加载页面时,会创建一个nodeList,它看起来像这样:

[text, h4, text, span, br, input, br, span, br, input, br, span, br, input, br, span, br, input, br]

我创建了一个简单的for循环,循环遍历所有这些元素,并从DOM中删除它们中的每一个。 (所有元素都在<section>

这是循环:

        for(element in videoTitlesElement.childNodes){
            if(!isNaN(element)){
                videoTitlesElement.removeChild(
                        videoTitlesElement.childNodes[element]);
            }
        }

但是,在循环结束时,nodeList看起来像这样:

[h4, span, input, span, input, span, input, span, input]

并非所有元素都被删除。为什么呢?

感谢。

3 个答案:

答案 0 :(得分:11)

两件事。首先,当您重复数字索引时,请不要使用for ... in;使用普通的for循环。然后,您不会需要isNaN()检查,而且通常更安全。

第二个问题是当你删除一个孩子时,你改变了列表的长度。如果你删除了孩子0,那么曾经是孩子1的孩子就变成了孩子0.因此,你真正想要的是一个简单的while循环:

while (videoTitlesElement.childNodes.length)
  videoTitlesElement.removeChild(videoTitlesElement.childNodes[0]);

或更简单:

while (videoTitlesElement.firstChild)
  videoTitlesElement.removeChild(videoTitlesElement.firstChild);

我还应该注意(假设您正在使用HTML DOM),通过简单地通过.innerHTML进行爆破,可以更轻松地清除元素的所有子节点:

videoTitlesElement.innerHTML = "";

答案 1 :(得分:4)

正在迭代的列表(videoTitlesElement.childNodes)在迭代期间被突变。尝试迭代原始列表的副本:

var children = [].slice.call(videoTitlesElement.childNodes);

for(element in children){
    if(!isNaN(element)){
         videoTitlesElement.removeChild(videoTitlesElement.childNodes[element]);
    }
}

答案 2 :(得分:3)

如果你看看你的结果,你会注意到你正在跳过每一秒。

如果您将此想象为带有迭代器的for循环,则每次都会递增迭代器,但在再次递增之前从同一个集合中删除一个项目。这意味着在第一次启动循环时索引为1的项目在删除数组中的第一个项目后位于索引0。因此,当您去查看索引1时,您已跳过该元素。这一直持续到循环结束,所以你错过了每一秒。