kael.shipman Posted November 29, 2007 Share Posted November 29, 2007 Hey everyone, I've been having this problem forever and haven't found a fix for it. I'll create an object, then have some function that iterates over an array of elements, attaching an event to each one. The event will contain a reference to a counting variable (it'll be more clear below). However, instead of the function for each object referencing the variable at the time of it's iteration, each function references the variable as it stands at the end of execution of the parent function, meaning that if there are 10 elements in the array, they all end up calling onclickFunction(n), where n = 10 instead of n = 0, n = 1, n = 2, etc.... Example: function myObject() { this.elements = [ 'element0', 'element1', 'element2', 'element3' ]; this.attachEvents(); } myObject.prototype = { constructor : this, attachEvents : function() { var self = this, i, obj; for(i = 0; i < this.elements.length; i++) { obj = document.getElementById(this.elements[i]); addListener(obj, function() { self.doSomething(i); return; }); } }, doSomething : function(n) { alert(n); } } //Just for reference.... function addListener(element, type, func, overwrite, bubbling) { if (typeof element == 'string') element = $(element); if (!element) return throwError('global::addListener - element not found'); bubbling = bubbling || false; overwrite = overwrite || false; if (overwrite) element['on'+type] = ''; if(window.addEventListener) { element.addEventListener(type, func, bubbling); return true; } else if(window.attachEvent) { element.attachEvent('on' + type, func); return true; } return throwError('global:addListener - couldn\'t attach event to element'); } Now if I were to create one such object on a page with all the required HTML in place, when I clicked element0, it would alert "4", just as it would when I clicked any of the other elements because it's referencing the variable "i" at the end of execution of the parent function "attachEvents". I know this has to do with closures, but I haven't wrapped my head around those yet. Maybe this is a good place to start. So how do I get it to reference the correct number? It seems to me that there's no way to use variables to do it because you're always setting variables with variables, and at the end, they're all still going to reference a variable that has been incremented since the function was created. The use of addListener() actually leads right into another question I have about transferring ownership, but take a look at my next post for that. Thanks for any help you can offer! -kael Quote Link to comment Share on other sites More sharing options...
roopurt18 Posted November 29, 2007 Share Posted November 29, 2007 Try changing this line: addListener(obj, function() { self.doSomething(i); return; }); to: addListener(obj, function() { var save_i = i; self.doSomething(save_i); return; }); Quote Link to comment Share on other sites More sharing options...
kael.shipman Posted November 30, 2007 Author Share Posted November 30, 2007 Unfortunately, that still references the i variable which still returns the value at the end of the parent function execution when referenced. I've tried it already and got the same result. Thanks though; any other ideas? Quote Link to comment Share on other sites More sharing options...
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.