I'm having several div's #mydiv1
, #mydiv2
, #mydiv3
, ... and want to assign click handlers to them:
$(document).ready(function(){
for(var i = 0; i < 20; i++) {
$('#question' + i).click( function(){
alert('you clicked ' + i);
});
}
});
But instead of showing 'you clicked 3'
when click on #mydiv3
(as for every other click) I get 'you clicked 20'
. What am I doing wrong?
It's a common mistake to create closures in loops in Javascript. You need to have some sort of callback function like this:
Update June 3, 2016: since this question is still getting some traction and ES6 is getting popular as well, I would suggest a modern solution. If you write ES6, you can use the
let
keyword, which makes thei
variable local to the loop instead of global:It's shorter and easier to understand.
Using on to attach the 'click' handler you can use the event data in order to pass your data like in:
To clarify, i is equal to 20 because the click event won't have fired until after the loop has finished.
You can get by with assigning the click handler once (or at least not making many unnecessary closures). Put all the divs in one class
mydivs
, then:This looks at the element's ID to get its number, using the
slice
string method to strip the initial letters off.Note: It may be better to use
instead of
Generally, if you are looking to assign click handles to a large number of items, you want to have a container (higher level div) that interprets the clicks for you, as the click bubbles up from the dom.