JS removeChild只能工作一半的时间

时间:2023-02-09 23:30:27
var graph = document.getElementById('graph');
Array.prototype.forEach.call(document.getElementsByClassName('release'),graph.removeChild.bind(graph));

In Firefox and Safari (haven't tested others) this removes only the even indexed elements, why?

在Firefox和Safari(没有测试过其他人)中,这只删除了偶数索引元素,为什么?

The HTMLCollection is indexed from 0 to the correct length incrementing by 1, and all elements are present. I get the same behavior with a normal for loop too, so it's probably not some weird forEach incompatibility. In fact if I use the function function(e,i,a){console.log(e.innerHTML);graph.removeChild(e)} instead, all the innerHTML gets logged, but still only the even indexed nodes get removed.

HTMLCollection从0索引到正确的长度,递增1,并且所有元素都存在。我也得到了与正常for循环相同的行为,所以它可能不是一些奇怪的每个不兼容性。实际上,如果我使用函数函数(e,i,a){console.log(e.innerHTML); graph.removeChild(e)},则会记录所有innerHTML,但仍然只删除偶数索引节点。

1 个解决方案

#1


This is because you are using getElementsByClassName which returns live HTMLCollection. So what happens is that index of this collection shifts once the item is removed (collection is updated automatically), which results in undeleted left-over items.

这是因为您使用getElementsByClassName返回实时HTMLCollection。因此,一旦项目被移除(集合自动更新),该集合的索引就会发生变化,从而导致未删除的剩余项目。

var graph = document.getElementById('graph');
Array.prototype.forEach.call(document.getElementsByClassName('release'), graph.removeChild.bind(graph));
<div id="graph">
    <div class="release">release 1</div>
    <div class="release">release 2</div>
    <div class="release">release 3</div>
</div>

Use non-live NodeList, for example returned by querySelectorAll:

使用非实时NodeList,例如querySelectorAll返回:

var graph = document.getElementById('graph');
Array.prototype.forEach.call(document.querySelectorAll('.release'), graph.removeChild.bind(graph));

var graph = document.getElementById('graph');
Array.prototype.forEach.call(document.querySelectorAll('.release'), graph.removeChild.bind(graph));
<div id="graph">
    <div class="release">release 1</div>
    <div class="release">release 2</div>
    <div class="release">release 3</div>
</div>

#1


This is because you are using getElementsByClassName which returns live HTMLCollection. So what happens is that index of this collection shifts once the item is removed (collection is updated automatically), which results in undeleted left-over items.

这是因为您使用getElementsByClassName返回实时HTMLCollection。因此,一旦项目被移除(集合自动更新),该集合的索引就会发生变化,从而导致未删除的剩余项目。

var graph = document.getElementById('graph');
Array.prototype.forEach.call(document.getElementsByClassName('release'), graph.removeChild.bind(graph));
<div id="graph">
    <div class="release">release 1</div>
    <div class="release">release 2</div>
    <div class="release">release 3</div>
</div>

Use non-live NodeList, for example returned by querySelectorAll:

使用非实时NodeList,例如querySelectorAll返回:

var graph = document.getElementById('graph');
Array.prototype.forEach.call(document.querySelectorAll('.release'), graph.removeChild.bind(graph));

var graph = document.getElementById('graph');
Array.prototype.forEach.call(document.querySelectorAll('.release'), graph.removeChild.bind(graph));
<div id="graph">
    <div class="release">release 1</div>
    <div class="release">release 2</div>
    <div class="release">release 3</div>
</div>