如何使用闭包在 Javascript for 循环中创建事件侦听器?

How to use closures to create event listeners in a Javascript for loop?

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 元素(它们都有 class 或 char)创建鼠标悬停事件侦听器。一旦鼠标悬停,它应该执行 mouseoverCheck() 函数并传入创建该事件侦听器时的任何 i 。所以第203个事件监听器应该传入203。但事实并非如此。现在,它传递了我认为是循环完成之前的最后一个值 i

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

它不起作用,因为

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

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

    });

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

你应该 return 来自 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)));
} 

这是一个fiddle:https://jsfiddle.net/qshnfv3q/

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)


}