5

我试图了解向事件侦听器添加函数时的区别以及它的含义。

var buttons = document.getElementsByTagName('button');
for (i = 0, len = 3; i < len; i++) {
    var log = function(e) {
        console.log(i);
    }
    buttons[0].addEventListener("click", log);
}

for (i = 0, len = 3; i < len; i++) {
    function log(e) {
        console.log(i);
    }
    buttons[1].addEventListener("click", log);
}

http://jsfiddle.net/paptd/

第一个按钮触发console.log3 次,而第二个按钮仅触发一次。

在正常情况下将函数添加到事件侦听器时,为什么以及应该使用什么?

4

1 回答 1

4

好吧,有几点注意事项:

  • 第一个log在每次迭代中创建一个新函数,因此每次添加另一个事件侦听器时都会添加一个新函数。
  • 第二个创建一个全局(阅读关于提升)log函数,如果多个相同的 EventListeners 注册在同一个 EventTarget 上,具有相同的参数,重复的实例将被丢弃。它们不会导致 EventListener 被调用两次。

眼镜:

使用参数 type、listener 和 useCapture 的相同值对同一个 EventTarget 重复调用 addEventListener(或 removeEventListener)无效。这样做不会导致事件侦听器被多次注册,也不会导致触发顺序发生变化。

感谢Rob W.

所以第二次和第三次迭代什么都不做。

  • 您还有一个关闭问题,最后一次迭代设置i3,这就是控制台中显示的内容。

带封闭的固定版本:

var buttons = document.getElementsByTagName('button');
for (i = 0, len = 3; i < len; i++) {
    var log = (function closure(number) {
        return function () {
            console.log(number);
        }
    })(i);

    buttons[0].addEventListener("click", log);
}

演示

于 2013-05-31T09:18:23.840 回答