我想将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);
}
});
}
};
答案 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
(通过将其作为参数传递给匿名函数)。您的实际处理程序使用该范围中的值,特别是迭代。