Javascript 将removeChild与HTMLCollection一起使用

Javascript 将removeChild与HTMLCollection一起使用,javascript,removechild,getelementsbyclassname,nodelist,htmlcollection,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.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
这就像预期的那样,它会删除所有找到的元素。现在考虑这个 代码:


它只删除了找到的元素的一半。是什么导致了这种情况?

querySelectorAll
返回一个非活动的
节点列表
getElementsByClassName
返回一个活动的
HTMLCollection
。前者的行为类似于任何数组:遍历数组,然后对每个元素执行某些操作。但是live
HTMLCollection
是不同的—它的内容随时反映DOM中的当前情况;如果从DOM中删除元素,它将消失在
xr
中,如果向DOM中添加符合选择器的元素,它将出现在
xr
中,即使在运行
getElementsByClassName
之后也是如此

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

无论何时在live
HTMLCollection
上进行操作,都可以从后到前进行操作,这样消失的元素就不会把您弄得一团糟,或者克隆
HTMLCollection
以将其元素固定到位,或者只需执行循环删除
xr[0]
,直到
xr
为空。

这对您有帮助。更短的
while(xr[0])xr[0].parentNode.removeChild(xr[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