Javascript 因为…在循环中没有在所有属性中循环?

Javascript 因为…在循环中没有在所有属性中循环?,javascript,for-loop,for-in-loop,nodelist,Javascript,For Loop,For In Loop,Nodelist,加载页面时,会创建一个节点列表,如下所示: [text, h4, text, span, br, input, br, span, br, input, br, span, br, input, br, span, br, input, br] [h4, span, input, span, input, span, input, span, input] 我为创建了一个简单的循环,循环遍历所有这些元素,并从DOM中删除它们中的每一个。(所有元素都在中) 以下是循环: for

加载页面时,会创建一个节点列表,如下所示:

[text, h4, text, span, br, input, br, span, br, input, br, span, br, input, br, span, br, input, br]
[h4, span, input, span, input, span, input, span, input]
我为创建了一个简单的
循环,循环遍历所有这些元素,并从DOM中删除它们中的每一个。(所有元素都在
中)

以下是循环:

        for(element in videoTitlesElement.childNodes){
            if(!isNaN(element)){
                videoTitlesElement.removeChild(
                        videoTitlesElement.childNodes[element]);
            }
        }
但是,在循环结束时,节点列表如下所示:

[text, h4, text, span, br, input, br, span, br, input, br, span, br, input, br, span, br, input, br]
[h4, span, input, span, input, span, input, span, input]
并非所有元素都被移除。为什么?


谢谢。

两件事。首先,不要将
用于。。。在
中迭代数值索引时;对
循环使用普通的
。这样您就不需要进行
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 = "";

如果您查看结果,您会注意到您正在跳过每一个项目


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

迭代的列表(
VideoTitleElement.childNodes
)在迭代过程中会发生变化。尝试迭代原始列表的副本:

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

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

因为您在循环集合时正在修改集合。假设集合中有三个元素
[a、B、C]
for..in
循环内部将有一个索引器来跟踪当前元素。所以索引器在开始时是0,它指向元素
A
。然后删除第一个元素,第二个元素
B
,现在成为第一个元素。索引器现在处于高级状态,并指向1。现在,索引1中的元素
C
,被删除。正如您可能看到的,索引0处的元素,
B
,未被触及并被跳过。简单的情况几乎是正确的,但这里:
.removeChild(firstChild)
未定义
firstChild
。谢谢!很好的解释。“清除”innerHTML在我的情况下不是最好的,我还读到一个接一个地删除元素通常要快得多。@aCodingN00b我会非常惊讶地发现,一个接一个地删除节点比只清除
.innerHTML
@Pointy@aCodingN00b要快得多。这个问题很老了,我不相信大多数评论。请注意,使用
for..in
来迭代阵列是不受欢迎的。