简单js forloop只迭代一次

问题描述 投票:1回答:4

我有一个JS for循环,该循环遍历具有特定类的所有元素,然后删除该类。但是,虽然循环对找到的第一个元素起作用,但随后它停止了。我看不到任何错误,我已经在try / catch中尝试过,也看不到其他任何可能导致问题的原因。有没有人有什么建议?谢谢:)

let visibleTags = document.getElementsByClassName('show');
console.log(visibleTags.length) // length is 2

for (let index = 0; index < visibleTags.length; index++) {
   console.log(index); // 0
   visibleTags[index].classList.remove('show'); // removes 'show' from element 0
}

// element 1 still has the 'show' class and was not touched by the loop... ?
javascript for-loop
4个回答
1
投票

[visibleTags是一个“实时” DOM查询-其中的元​​素将随着DOM的变化而变化。

因此,当您从元素中删除show类时,它同时也会从visibleTags中消失,因为您的查询是针对具有show类的元素。因此,一旦删除该类,visibleTags.length就会降为1,并且循环将退出,因为循环计数器已经为1。

有多种方法可以使用此方法:

  • 一种解决方案是向后运行循环,以便使其从visibleTags.length开始并倒计数为零。这样,您可以删除元素,长度将减小,但是您将移至上一个元素,然后继续循环。

  • 另一种选择是将循环作为while循环运行,并不断删除第一项:即:

    while (visibleTags.length) {
        visibleTags[0].classList.remove('show');
    }
    

    这将是我的首选解决方案。

  • 最后,您可以选择创建一个可以循环遍历的元素的非实时数组。您可能不需要这样做,但是如果以后需要再次遍历相同的元素列表(例如,可能要还原show类),则这可能是一个有用的选项。


0
投票

这是因为document.getElementsByClassName()引用了与您的类匹配的元素的[[actual数组。

因此,在迭代和更改其类时,元素本身不再属于数组,因此索引变为index-1。

一种解决方法,如果没有其他路径可以到达对象,则依赖于另一个类/选择器来检索元素列表:

let visibleTags = document.getElementsByClassName('test'); console.log(visibleTags.length) // length is 2 for (let index = 0; index < visibleTags.length; index++) { console.log(index); // 0 visibleTags[index].classList.remove('show'); // removes 'show' from element 0 }
.test { 
  width: 300px;
  height: 300px;
  border: 1px solid #ccc;
}

.show {
  background-color: red;
}
<div>
  <div class="show test">1</div>
  <div class="show test">2</div>
</div>

0
投票
您不应该使用索引,visibleTag是一个实时集合,并且您正在修改部分选择标准(show类),因此集合本身将发生变化。由于您想从具有show类的所有内容中删除show,因此最好使用这样的while循环:

let shown = document.getElementsByClassName('show'); while(shown.length > 0) { shown[0].classList.remove('show'); }
<div>
  <div class="show">1</div>
  <div class="show">2</div>
  <div class="show">3</div>
  <div class="show">4</div>
</div>

0
投票
尝试使用此功能:

function removeClassFromElements(className) { document .querySelectorAll(`.${className}`) .forEach(el => el.classList.remove(className)); }

针对您的情况:

removeClassFromElements('show');

© www.soinside.com 2019 - 2024. All rights reserved.