0

我想将 javascript 中的事件侦听器应用于循环内的元素。事件名称在循环中是可变的。当我尝试使用我的代码时,它不工作只有最后一个 addEventListener 工作?我要添加的事件是:单击和鼠标输入。当我单击该项目时,触发的是 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);
            }

        });


    }


};
4

1 回答 1

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

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

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

于 2013-10-24T14:09:24.493 回答