Philip Philip - 5 months ago 13
jQuery Question

Assign click handlers in for loop

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?

Answer

It's a common mistake to create closures in loops in Javascript. You need to have some sort of callback function like this:

function createCallback( i ){
  return function(){
    alert('you clicked' + i);
  }
}

$(document).ready(function(){
  for(var i = 0; i < 20; i++) {
    $('#question' + i).click( createCallback( i ) );
  }
});

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 the i variable local to the loop instead of global:

for(let i = 0; i < 20; i++) {
  $('#question' + i).click( function(){
    alert('you clicked ' + i);
  });
}

It's shorter and easier to understand.

Comments