为什么我的JavaScript for循环跳过元素?

时间:2016-08-19 15:11:04

标签: javascript for-loop

我有一个for循环,它贯穿一组元素,从每个元素中删除'selected'类。但是,它会跳过每一次迭代。我发现我可以通过添加j--来解决这个问题,我想这很好,除了延长我的代码。但是我想知道是否有人可以解释为什么它会跳过并且可能会建议一种更简洁的方式来编写这段代码? (我还在学习绳索,并希望确保我理解发生了什么。)

var selections = document.getElementsByClassName(name + 'selected');
for (var j = 0; j < selections.length; j++) {
  selections[j].classList.remove('selected');
  j--; // the fix
}

// where name is a present variable

谢谢你的时间!

2 个答案:

答案 0 :(得分:12)

这是因为getElementsByClassName()会返回live HtmlCollection;换句话说,HtmlCollection会自动更新,因此当您从元素中删除“已选择”类时,该元素将从集合中删除

你可以这么做;

var selections = document.getElementsByClassName(name + 'selected');
while (selections.length) {
    selections[0].classList.remove('selected');
}

......相反。

或者,正如评论中Paul Roub所指出的那样,您可以反向迭代;

for (var j = selections.length-1; j >= 0; j--) {
  selections[j].classList.remove('selected');
}

或者,您可以通过将集合复制到数组来完全避免实时HtmlCollection;

var selections = Array.prototype.slice.call(document.getElementsByClassName(name + 'selected'));
for (var j = 0; j < selections.length; j++) {
  selections[j].classList.remove('selected');
}

...或者,正如评论中Yury Tarabanko所指出的那样,使用querySelectorAll代替;

var selections = document.querySelectorAll('.' + name + 'selected');
for (var j = 0; j < selections.length; j++) {
  selections[j].classList.remove('selected');
}

答案 1 :(得分:1)

getElementsByClassName是一个实时HTML集合,因此当您删除该元素的类时,它将被更新。这意味着在索引现在位于删除元素的位置之后,它曾经是索引中的内容。

var selections = document.getElementsByClassName('selected');
console.log("before: ", selections.length);
selections[0].classList.remove("selected");
console.log("after: ", selections.length);
<div class="selected"></div>
<div class="selected"></div>
<div class="selected"></div>
<div class="selected"></div>
<div class="selected"></div>

向后循环有效,因为物品没有向下移动。

选项选项是执行while循环。

var selections = document.getElementsByClassName('selected');
while(selections.length) {
    selections[0].classList.remove("selected");
}