【问题标题】:How to use closures to create event listeners in a Javascript for loop?如何使用闭包在 Javascript for 循环中创建事件侦听器?
【发布时间】:2016-03-29 11:57:14
【问题描述】:

HTML

<span class="char" id="0">?</span>
<span class="char" id="1">!</span>
<span class="char" id="2">"</span>
<span class="char" id="3">/</span>
<span class="char" id="4">%</span>
<span class="char" id="5">$</span>
...

JavaScript

var charElems = document.getElementsByClassName('char');

for (var i=0; i < charElems.length; i++) {

    charElems[i].addEventListener('mouseover',function() {

        (function(j) {mouseoverCheck(j);}(i));

    });

}

我有一堆(数百个)span 元素,其 ID 为数字(从 0 开始并以 1 递增)。这个循环应该做的是为所有span 元素(它们都有一个char 类)创建鼠标悬停事件侦听器。一旦鼠标悬停,它应该执行mouseoverCheck() 函数并传入任何i 在创建事件侦听器时的值。所以第 203 个事件监听器应该传入203。但事实并非如此。现在,它传入了我认为i 在循环完成之前的最后一个值。

我试图使用 IIFE 和闭包来确保每个事件侦听器在创建时获得 i 的值,而不是在调用函数时获得它的值。显然,我没有正确地做到这一点,但我相当肯定关闭是我问题的关键。任何人都可以阐明如何正确执行此操作吗?我以为我理解了闭包,但显然我不...

【问题讨论】:

  • 试试这个:jsfiddle.net/5wg835m6
  • 如果您真正需要的只是索引号,我不会使用闭包。我只是将索引直接放在 DOM 元素上:charElems[i].__index = i;,然后使用mouseoverCheck(this.__index)

标签: javascript for-loop closures addeventlistener


【解决方案1】:

它不起作用,因为

charElems[i].addEventListener('mouseover',function() {

        (function(j) {mouseoverCheck(j);}(i));

    });

addEventListener() 只是分配了一个处理程序,到该处理程序被调用时,i 将是 6。

你应该从 IIFE 返回一个处理程序

var charElems = document.getElementsByClassName('char');

  for (var i=0; i < charElems.length; i++) {

      charElems[i].addEventListener('mouseover', (function(temp) {

        return function(){
             var j = temp;
             //mouseoverCheck(j);
             console.log(temp);
       }
    }(i)));
} 

这是一个小提琴:https://jsfiddle.net/qshnfv3q/

【讨论】:

  • 提供的小提琴中有一些语法错误。试试这个:jsfiddle.net/5wg835m6
  • @RayonDabre 我忘了更新更改,谢谢指点
  • 原来我的误解是事件监听器的工作方式,而不是关闭!这解决了我的问题,非常感谢!
【解决方案2】:
var charElems = document.getElementsByClassName('char');

for (var i = 0; i < charElems.length; i++) {

    //close...
    //charElems[i].addEventListener('mouseover',function() {
    //    (function(j) {mouseoverCheck(j);}(i));
    //});

    //like this
    (function(el, x) {
        el.addEventListener("mouseover", function() {
            mouseoverCheck(x);
        });
    })(charElems[i], i)


}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2012-10-29
    • 1970-01-01
    • 1970-01-01
    • 2016-03-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多