我有一个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... ?
[visibleTags
是一个“实时” DOM查询-其中的元素将随着DOM的变化而变化。
因此,当您从元素中删除show
类时,它同时也会从visibleTags
中消失,因为您的查询是针对具有show
类的元素。因此,一旦删除该类,visibleTags.length
就会降为1
,并且循环将退出,因为循环计数器已经为1。
有多种方法可以使用此方法:
一种解决方案是向后运行循环,以便使其从visibleTags.length
开始并倒计数为零。这样,您可以删除元素,长度将减小,但是您将移至上一个元素,然后继续循环。
另一种选择是将循环作为while
循环运行,并不断删除第一项:即:
while (visibleTags.length) {
visibleTags[0].classList.remove('show');
}
这将是我的首选解决方案。
最后,您可以选择创建一个可以循环遍历的元素的非实时数组。您可能不需要这样做,但是如果以后需要再次遍历相同的元素列表(例如,可能要还原show
类),则这可能是一个有用的选项。
这是因为document.getElementsByClassName()
引用了与您的类匹配的元素的[[actual数组。
一种解决方法,如果没有其他路径可以到达对象,则依赖于另一个类/选择器来检索元素列表:
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>
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>
function removeClassFromElements(className) {
document
.querySelectorAll(`.${className}`)
.forEach(el => el.classList.remove(className));
}
针对您的情况:
removeClassFromElements('show');