【问题标题】:How to add eventHandlers with local variables in a loop如何在循环中添加带有局部变量的事件处理程序
【发布时间】:2020-01-07 07:46:17
【问题描述】:

我确信我曾经知道这一点,但我已经离开一段时间了,我再也想不通了。

假设我有一组按钮(“按钮 A”、“按钮 B”、“按钮 C”,由 .getElementsByClassName("button") 检索的 NodeList 表示。

我现在想向这些事件添加一个 EventHandler,它使用一些在创建处理程序时按值传递的局部变量。举个最简单的例子,让我们使用:

for (var i = elems.length - 1; i >= 0; i--) {
    var inner = elems[i].innerHTML;
    elems[i].onclick = function(){window.alert("Clicked on "+inner+" which is element number "+i)};
}

这里想要的结果是,当点击按钮 B 时,我得到

Clicked on Button B which is element number 1

但是,所有按钮都会产生

Clicked on Button A which is element number -1

我明白为什么会发生这种情况,但是我需要如何更改代码才能实现前者?如果这是相关的,在最终的事件处理程序中 i 不会被自己使用,而是再次引用 elem[i],它作为参数传递给处理程序。

【问题讨论】:

标签: javascript scope dom-events pass-by-value


【解决方案1】:

使用let 声明变量。这将为变量创建一个块作用域,并在循环中保留正确的值:

for (let i = elems.length - 1; i >= 0; i--) {

演示:

let elems = document.querySelectorAll('button');
for (let i = elems.length - 1; i >= 0; i--) {
  var inner = elems[i].innerHTML;
  elems[i].onclick = function(){window.alert("Clicked on "+inner+" which is element number "+i)};
}
<button type="button">Button A</button>
<button type="button">Button B</button>
<button type="button">Button C</button>

【讨论】:

  • 谢谢。事实证明,当我更活跃于 JS 时,我也不知道这一点。是不是有点新意?
  • @Tobl,不客气,是的,它是相对较新的 (ES6) 功能。
【解决方案2】:
var elems = document.getElementsByClassName('btn');
for (var i = elems.length - 1; i >= 0; i--) {
  (function(i) {
    var inner = elems[i].innerHTML;
    elems[i].onclick = function(){window.alert("Clicked on "+inner+" which is element number "+i)};
  })(i);
}

<button type="button" class="btn">Button A</button>
<button type="button" class="btn">Button B</button>
<button type="button" class="btn">Button C</button>

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2015-08-24
    • 1970-01-01
    • 2019-07-01
    • 1970-01-01
    • 1970-01-01
    • 2011-07-05
    • 1970-01-01
    • 2015-04-05
    相关资源
    最近更新 更多