【问题标题】:For loop only iterates once when trying to remove classes from elements尝试从元素中删除类时,for循环仅迭代一次
【发布时间】:2015-12-31 17:00:30
【问题描述】:

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

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");
    }
}

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

【问题讨论】:

    标签: javascript dom for-loop


    【解决方案1】:

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

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

    解决此问题的一种方法是将节点列表转换为数组:

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

    【讨论】:

    • 这解决了我的问题,将 j 设置为 prev_connected.length-1 然后递减。是的,一定是因为它是一个实时节点列表。
    【解决方案2】:

    getElementsByClassName 的结果是实时的,这意味着当您删除类属性时,它也会从结果中删除该元素。使用 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>

    【讨论】:

      【解决方案3】:

      你应该在相反的方向迭代并使用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

      【讨论】:

        猜你喜欢
        • 2019-11-03
        • 1970-01-01
        • 2015-10-24
        • 1970-01-01
        • 2020-07-19
        • 2016-05-10
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多