I see Klaus posted a very
clean solution, but just to help you understand what went wrong...
Pretend you are the _javascript_
interpreter, executing the code inside your click handler function
after a click. You encounter the variable name "i" and need to find its
value. Since "i" isn't defined in the innermost function, you look
outside and find the "i" that was used as the loop variable in your
outer function.
But the for loop has already
finished executing at this point! What's the value of "i" after the for
loop is done? 30.
If Klaus's solution didn't
work for any reason, or if you ever need a solution that will work in
any _javascript_ environment, you can simply wrap your code inside a
function to capture the value of "i" each time through the loop:
(function( i ) {
$("##id_" + i).click(
function(){
foo(i,ConstantArgument);
}
);
})( i );
Now when you pretend to be the
_javascript_ interpreter and find a value for "i" in that inner foo()
call, you'll find the "i" in this wrapper function - and that's a new
"i" each time because this wrapper function get called separately each
time through the loop.
It doesn't have to be an
anonymous function - it's probably more readable to break it out as a
separate named function. While we're at it, let me show you another way
to write your code that builds the HTML string.
function add(
i ) {
$('#MyContainerID').append([
'<span id="id_', i, '" class="MyClass" value="', i, '">',
i,
'</span>'
].join(''));
$('#id_' + i).click( function(){
foo(i,ConstantArgument);
});
}
Call add(i) in your for loop
and you are golden. Place the add() function definition inside the same
function as the for loop, so it can pick up the constantArgument.
But watch out for page load
time when you are setting up this many event handlers. I was doing this
for a poup calendar widget, and the load time was noticeable on a slow
machine. I ended up installing a single event handler for the entire
calendar and doing my own hit testing on the click and other mouse
events. It was more work, but it makes the calendar open faster.
(Note that none of the code
above is tested! But it should be pretty close.)
-Mike
I've got a function that builds several elements on a page with a
certain class. I've successfully used jQuery to add mouseover and
mouseout events to all the elements with that certain class, and it
works beautifully. I couldn't be happier. :0)
So, now I need to add a click event to each of those elements. The
trouble is, that not each of those click events will be exactly the
same. Each will call the same function but with slightly different
arguments (one constant and one variable). After playing with a couple
of ideas on how to use jQuery to accomplish this, I ended up with the
following:
... inside a JS for loop with a counter 'i' ...
$("##MyContainerID").append("<span id=\"id_" + i + "\"
class=\"MyClass\" value=\"" + i + "\">" + i + "</span>");
$("##id_" + i).click(
function(){
foo(i,ConstantArgument);
}
);
... end loop ...
The loop creates each of these elements on the page and I was hoping it
would then assign a click event to each element (made unique with the
id), and this seemed to work. However when I click on each of the
elements in turn I can see that they are each calling the function
(foo) with the same arguments (30,40). While 40 is the constant
argument and is correct, the other argument was supposed to range from
1 - 29 (the number of elements in this particular list).
I'm a bit confused I thought this should work. Can anyone shed any
light on what I may be doing wrong? Is there a different approach i
need to take? Is there a better jQueryie-type way to accomplish this
task that will make life easier?
_______________________________________________
jQuery mailing list
discuss@jquery.com
http://jquery.com/discuss/