【问题标题】:Issue while avoiding forEach loop [duplicate]避免forEach循环时出现问题[重复]
【发布时间】:2017-12-27 23:52:43
【问题描述】:

这是我上一个问题javascript dynamically adding and removing classes的扩展

根据给出的答案,它使用forEach 循环,但我尝试使用for 循环并实现相同:

function test() {
  var paragraphs = document.querySelectorAll("#divid p[id ^= 'p']");
  for(index =0; index < paragraphs.length; index++) {
    paragraphs[index].addEventListener('click', (e) => {
      for (i = 0; i < index; i++) {
        paragraphs[i].classList.remove('active');
      }
      for (i = index; i < paragraphs.length; i++) {
        paragraphs[i].classList.add('active');
      }
    });
  }
}

但我收到以下错误:

11 Uncaught TypeError: Cannot read property 'classList' of undefined
    at HTMLSpanElement.paragraphs.(anonymous function).addEventListener

我还想删除上面代码中的特殊符号=&gt; 并解决问题。

【问题讨论】:

  • “避免 forEach 循环” - 但是……为什么?
  • 在测试我的团队时报告说某些浏览器不支持此功能,我不确定是哪个浏览器。
  • 是的,IE
  • @user3181365 那些浏览器不支持箭头功能,classList 也不支持。
  • @YuryTarabanko,哦,你能告诉我在这种情况下的替代解决方案是什么。我想在不使用 foreach 的情况下实现相同的输出

标签: javascript


【解决方案1】:

您遇到了经典的“循环内闭包”问题,您在循环内创建的所有闭包(作为事件处理程序创建的函数)之间的循环索引变量是相同的。

解决方案是将事件处理函数包装在一个立即调用的函数表达式中,将索引变量传递给该函数表达式,将其当前值绑定到范围。

function test() {
  var paragraphs = document.querySelectorAll("#divid p");
  for (index = 0; index < paragraphs.length; index++) {
    paragraphs[index].addEventListener('click', (function(index) {
      return function() {
        var i;
        for (i = 0; i < index; ++i) {
          paragraphs[i].classList.remove('active');
        }
        for (i = index; i < paragraphs.length; ++i) {
          paragraphs[i].classList.add('active');
        }
      }
    })(index));
  }
}

test();
p.active {
  color: red;
}
<div id="divid">
  <p>p1</p>
  <p>p2</p>
  <p>p3</p>
  <p>p4</p>
  <p>p5</p>
  <p>p6</p>
</div>

【讨论】:

  • 成功了,非常感谢