Reputation: 483
i want to apply event listeners in javascript to elements inside a loop. The event name is variable in the loop. When i try with my code it's not working only the last addEventListener is working ? The events i want to add are : click and mouseenter. When i click on the item, it's the mouseenter event which which is fired !
_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);
}
});
}
};
Upvotes: 0
Views: 883
Reputation: 27823
Your problem is one of closure.
Simplified, your code looks like this:
var events = ['click', 'mousedown'];
for (var i=0; i<events.length; i++) {
var a = events[i];
window.setTimeout(function(){
console.log(a);
},0);
}
The function there logs the variable defined in the outer scope. Both functions created (one for each iteration) print the same variable. At the time the functions are created the variable has different values, but when they are called, the variable has the value 'mousedown', so they will both log 'mousedown'.
What you want to do is create a local version of the a
variable to each function. But since it is a callback you're writing there, you can't alter the parameters. The solution is to wrap it in another function and use closures again (but properly this time):
for (var i=0; i<events.length; i++) {
var a = events[i];
window.setTimeout(function(obj){ return function(){
console.log(obj);
}}(a),0);
}
As you can see, you created a scope for each iteration where you save the current value of a
to obj
(by passing it as parameter to an anonymous function). Your actual handler uses the value in that scope, particular to the iteration.
Demo: http://jsbin.com/agoDaza/1/edit
Upvotes: 2