将 removeChild 与 HTMLCollection 一起使用

Using removeChild with 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

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

querySelectorAllreturns一个非直播NodeListgetElementsByClassNamereturns一场直播HTMLCollection。前者的行为类似于任何数组:遍历数组,然后为每个元素做一些事情。而直播HTMLCollection则不同——它的内容随时反映DOM中的当前情况;如果你从 DOM 中删除一个元素,它会在 xr 中消失,如果你向 DOM 添加一个适合选择器的元素,它将出现在 xr甚至在你之后[​​=45=]getElementsByClassName.

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

每当您在实时 HTMLCollection 上操作时,要么从后向前移动,以免消失的元素弄乱您,要么克隆 HTMLCollection 以将其元素固定到位,或者只是循环删除 xr[0] 直到 xr 为空。