How to use closures to create event listeners in a

2019-03-01 11:37发布

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));

    });

}

I have a bunch (hundreds) of span elements with numbers as IDs (starting from 0 and incrementing by 1). What this loop is supposed to do is create mouseover event listeners for all the span elements (which all have a class of char). Once moused over, it should excecute the mouseoverCheck() function and pass in whatever i was when that event listener was created. So the 203rd event listener should pass in 203. But it does not. Right now, it passes in what I believe is the last value i was before the loop completed.

I was attempting to use an IIFE and closure to make sure each event listener got i's value at the time it was created, instead of it's value when the function is called. Clearly, I didn't do it correctly, but I am fairly certain closure is the key to my problem. Can anyone shed some light on how to do this properly? I thought I understood closure, but clearly I do not...

2条回答
冷血范
2楼-- · 2019-03-01 12:02

it doesn't work because

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

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

    });

addEventListener() is just assigning a handler and by the time that handler is called i will be 6.

you should return a handler from an 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)));
} 

Here is a fiddle: https://jsfiddle.net/qshnfv3q/

查看更多
smile是对你的礼貌
3楼-- · 2019-03-01 12:12
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)


}
查看更多
登录 后发表回答