Reputation: 1265
im working on a project for which i coded a quick and dirty dom manipulation framework.. or function rather:
var $ = function(e, properties){
var elem = document.getElementById(e) || false;
if(!elem && properties){
elem = document.createElement('div');
elem.id = e;
for(i in properties){
switch(i){
case 'parent':
properties.parent.appendChild(elem);
break;
case 'events':
for(j in properties.events){
elem.addEventListener(j, function(e){
e.preventDefault();
properties.events[j](e, elem);
});
}
break;
default :
elem[i] = properties[i];
break;
}
}
}
return elem;
};
as long as im using one event listener throughout the project, everything seems to be working fine, however, when i add another element the events get mixed up, i get a click event where a contextmenu event should be emitted, things just become a mess. it seems to want to call the wrong function.
demonstration of the problem: fiddle
Upvotes: 0
Views: 85
Reputation: 413737
Variables "i" and "j" are global. They should be declared with var
in the function:
var i, j;
That won't fix it, however. Inside the event listener functions you create, there's still a reference to "j", and that's still going to be a reference from every handler to the very same variable. A variable can only have one value at a time, and that value will be whatever "j" was when the very last handler was assigned.
You need to add another layer of function call in order create a unique scope for each handler:
elem.addEventListener(j, function(jCopy) {
return function(e){
e.preventDefault();
properties.events[jCopy](e, elem);
};
}(j));
There are other ways of achieving the same thing, but they're all more or less the same idea. There are a zillion related questions on Stackoverflow.
Upvotes: 3