addEventListener,for(),index。怎么用封闭?

时间:2013-12-14 20:09:49

标签: javascript for-loop closures addeventlistener

我有这段代码:

var items = this.llistat.getElementsByTagName('a');

for( var i = 0; i < items.length; i++ ){    
  items[i].addEventListener('click', function(event) {
    alert( i );
  }, items[i]);
}

监听事件,但有3个项目,并且警告总是在任何元素上打印3(它不尊重索引),

Dosen't items[i]不应该做关闭工作吗?

谢谢!

2 个答案:

答案 0 :(得分:11)

不,addEventListener的第三个参数是useCapture。有关详细信息,请参阅MDN

但你可以使用:

for( var i = 0; i < items.length; i++ ){
    (function(i){
        items[i].addEventListener('click', function(event) {
            alert( i );
        }, false);
    })(i);
}

var handler = function(event) {
    var i = items.indexOf(this);
    alert( i );
};
for( var i = 0; i < items.length; i++ ){
    items[i].addEventListener('click', handler, false);
}

第一个为每个元素创建一个新的事件处理程序,因此需要更多内存。第二个重用同一个事件监听器,但使用indexOf,所以它更慢。

答案 1 :(得分:9)

这是一个经典的闭包问题:你必须创建一个新的函数绑定,而不是'i'变量,而是绑定时的值:

var items = this.llistat.getElementsByTagName('a');

for( var i = 0; i < items.length; i++ ) {
        items[i].addEventListener('click', listener.bind( null, i) );
}

function listener(index) {
         alert(index);
}