将removeChild与HTMLCollection一起使用

时间:2015-12-25 03:56:10

标签: javascript removechild getelementsbyclassname nodelist htmlcollection

考虑以下代码:

xr = document.querySelectorAll('.material-tooltip'); // NodeList
console.log(xr.length); // 50
for (ya of xr)
  ya.parentNode.removeChild(ya);
zu = document.querySelectorAll('.material-tooltip');
console.log(zu.length); // 0

这可以正常工作,它会删除所有找到的元素。现在考虑一下 代码:

xr = document.getElementsByClassName('material-tooltip'); // HTMLCollection
console.log(xr.length); // 50
for (ya of xr)
  ya.parentNode.removeChild(ya);
zu = document.getElementsByClassName('material-tooltip');
console.log(zu.length); // 25

只删除了一半找到的元素。造成这种情况的原因是什么?

1 个答案:

答案 0 :(得分:2)

querySelectorAll返回非实时NodeListgetElementsByClassName返回实时HTMLCollection。前者的行为与任何数组相同:您遍历数组,然后为每个元素执行某些操作。但是实时HTMLCollection是不同的 - 它的内容随时反映了DOM中的当前情况;如果你从DOM中删除一个元素,它会在xr中消失,如果你向DOM中添加一个适合选择器的元素,它甚至会在你运行{{1>后出现在xr中}}

让我们做getElementsByClassName ya的第一次迭代。您删除了0,它会从列表中消失。现在元素1是xr[0]; xr[0]变为ya;然后删除1(元素2),跳过元素1。然后删除xr[1](元素3),并跳过元素4 ...等。

每当你在实时xr[2]上进行操作时,要么从后到前进行,以便消失的元素不会弄乱你,或克隆HTMLCollection来修复其元素,或者只是执行循环删除HTMLCollection,直到xr[0]为空。