For循环只在尝试从元素中删除类时迭代一次

时间:2015-10-03 16:32:02

标签: javascript dom for-loop

在Javascript中,我有一个函数应该在页面上找到具有“connected”类的元素,当单击一个按钮时,这些元素的类被清除。我写了这段代码:

var prev_connected = document.getElementsByClassName("connected");
if (prev_connected.length > 0) {
    for (var j = 0; j < prev_connected.length; j++) {
        prev_connected[j].removeAttribute("class");
    }
}

但是,它只会删除页面上第一个“connected”元素的class属性。当我有两个“连接”元素时,我已经确认“prev_connected”数组确实包含2个值,但由于某种原因,for循环永远不会到达第二个。有什么我做错了吗?感谢。

3 个答案:

答案 0 :(得分:4)

getElementsByClassName的结果是实时的,这意味着当您删除class属性时,它也会从结果中删除该元素。使用querySelectorAll得到更广泛的支持并返回静态NodeList。

此外,您可以使用for ... in循环更轻松地迭代列表。

我不建议制作实时列表的额外副本以使其静态,您应该使用返回静态NodeList的方法。

var prev_connected = document.querySelectorAll(".connected");
document.getElementById('demo').onclick = function() {
    for(var i in Object.keys(prev_connected)) { 
        prev_connected[i].removeAttribute("class");
    }
}
.connected {
  background: rgb(150,200,250);
}
<div class="connected">Hello</div>
<div class="connected">Hello</div>
<div class="connected">Hello</div>
<div class="connected">Hello</div>
<div class="connected">Hello</div>
<button id="demo">Remove the classes!</button>

答案 1 :(得分:2)

这是因为prev_connected是一个实时节点列表。当您使用该类更新元素时​​,它会将其从节点列表中删除,这意味着节点列表的长度减少了1,这意味着j正在尝试在长度为1的节点列表中查找元素2,这就是为什么它不会在第一次迭代后工作。

您可以在this demo中的控制台中看到这种情况。

解决此问题的一种方法是将nodelist转换为数组:

var prev_connected = [].slice.call(document.getElementsByClassName("connected"));

答案 2 :(得分:0)

您应该以相反的方向进行迭代,并使用elem[i].classList.remove('name')从每个元素中移除类名Demo

document.getElementById("button").onclick = function () {
    var prev_connected = document.getElementsByClassName("connected");
    console.log(prev_connected);
    for (var i = prev_connected.length - 1; i >= 0; i--) {
        prev_connected[i].classList.remove("connected");
        console.log(i, prev_connected[i - 1]);
    }
}

还有另一个答案:https://stackoverflow.com/a/14409442/4365315