带有事件名称变量的addEventListener在循环中

时间:2013-10-24 12:39:23

标签: javascript

我想将javascript中的事件监听器应用于循环内的元素。事件名称在循环中是可变的。当我尝试使用我的代码时,它不工作只有最后一个addEventListener工作?我想添加的事件是:click和mouseenter。 当我点击该项目时,它是被触发的mouseenter事件!

_apply = function(trackEventData, trackEventItem) {

    var tmpData, i, j, eventType, eventAction;

    // get stringified json events
    tmpData = JSON.parse(trackEventData);
    for (i = 0; i < tmpData.length; i++) {
        // for each type in events

        eventType = Events.getEventTypeByKey(tmpData[i].key);
        eventAction = tmpData[i].actions;
        console.log('apply ' + eventType.event);
        // we add the event listener

        trackEventItem.addEventListener(eventType.event, function(e) {
            console.log('eventfired ' + eventType.event);
            e.preventDefault();
            // and for each action we add the function callback
            for (j = 0; j < eventAction.length; j++) {
                Events.getEventActionByKey(eventAction[j].value).action(eventAction[j].options);
            }

        });


    }


};

1 个答案:

答案 0 :(得分:2)

你的问题就是关闭。

简化,您的代码如下所示:

var events = ['click', 'mousedown'];
for (var i=0; i<events.length; i++) {
  var a = events[i];
  window.setTimeout(function(){
    console.log(a);
  },0);
}

该函数记录外部作用域中定义的变量。创建的两个函数(每次迭代一个)打印相同的变量。在创建函数时,变量具有不同的值,但是当它们被调用时,变量的值为“mousedown”,因此它们都会记录“mousedown”。

您要做的是为每个函数创建a变量的本地版本。但由于这是你在那里写的回调,你不能改变参数。解决方案是将它包装在另一个函数中并再次使用闭包(但这次正确):

for (var i=0; i<events.length; i++) {
  var a = events[i];
  window.setTimeout(function(obj){ return function(){
    console.log(obj);
  }}(a),0);
}

如您所见,您为每次迭代创建了一个范围,您将a的当前值保存到obj(通过将其作为参数传递给匿名函数)。您的实际处理程序使用该范围中的值,特别是迭代。

演示:http://jsbin.com/agoDaza/1/edit