views:

89

answers:

2

Hello,

I am a bit of a beginner with javascript and I can't think of a way around the folowing problem. I am using Mootools in this example, though this is not a Mootools question:

for (var i = 0; i < 5; i++) {
    myElement[i].addEvent('click', function () { otherFunction(i); });
}

Whenever someone clicks on myElement, otherFunction is called (good) but is passed 5 (bad). I know this is because it acesses i AFTER the loop finishes (when they click on the element), but I can't for the life of think of any alternative except for the monotonous

switch(i) {
    case 1: myElement[i].addEvent('click', function () { otherFunction(1); }); break;
    case 2: myElement[i].addEvent('click', function () { otherFunction(2); }); break;
    // ...
}

There's got to be a better way... I feel I'm missing something obvious

UPDATE: Added [i] index to myElement (oops)

Thanks, Cameron

+1  A: 

I agree with the comment questioning why you need five click handlers for a single element, but to accomplish what you desire you need to use a closure.

Take a look at this tutorial on JavaScript tutorials.

Update: For some code/syntax samples, take a look at this question I asked here on the very same subject - using closures for event handlers.

matt b
+2  A: 

Your code is an example of a closure - the anonymous function references the last value of i as it is effectively preserving that outer scope for later use when the function is called.

Here's one way you could fix it:

function getClickHandler(i)
{ 
   return function () { otherFunction(i); }
}

for (var i = 0; i < 5; i++) {
    myElement.addEvent('click', getClickHandler(i));
}

This moves the creation of the closure to another scope which will "preserve" each value of i

Another way would be to simply have a single click handler which can be assigned to each element and figures out which was clicked from the event object (assuming you want to attach these handlers to different elements, though you code suggests you want multiple handlers on the same element, which is a bit odd :)

Paul Dixon