3

Possible Duplicate:
Javascript infamous Loop problem?

For some reason I get "6" inside my function here for every div element:

for(var i = 1; i <= 5; i++){
  $('<div class="e-' + i + '"></div>').appendTo(something).click(function(){
    alert(i);  // <-- it's 6. wtf??
  });
}

instead of 1, 2, 3, etc.

The class on the other hand it appears to be correctly set..

What am I doing wrong?

Community
  • 1
  • 1
Alex
  • 66,732
  • 177
  • 439
  • 641
  • 1
    ref: http://stackoverflow.com/questions/1451009/javascript-infamous-loop-problem – Yoshi Apr 25 '12 at 14:13
  • This is called the "last one only" problem. Answer below sums it up nicely, and I wrote an article which contains it a while back: http://lynxphp.com/javascript/javascript-immediate-functions/ – callumacrae Apr 25 '12 at 14:16

2 Answers2

11

Your for loop is being executed at page load time. The alert only fires when there's a click event which is happening after the for loop has finished. Hence the value of i is now 6.

1) Page loads, for loop does its stuff...

2) Sometime later a click event is fired. the value of i at this time is 6 because the forloop has already completed.

Aidanc
  • 6,921
  • 1
  • 26
  • 30
5

The problem is that you need to create a closure to capture the value of i at the time you bind the click function.

Try this:

for(var i = 1; i <= 5; i++)
{
  $('<div class="e-' + i + '"></div>')
    .appendTo(something)
    .click(function(value)
    { 
      return function() { alert(value) };
    }(i));
}
wsanville
  • 37,158
  • 8
  • 76
  • 101
  • Why not use an anonymous function? It looks better. – callumacrae Apr 25 '12 at 14:17
  • also the `var fn` inside the loop is misleading as there is no block scope in js. – Yoshi Apr 25 '12 at 14:18
  • Cool, didn't know about the lack of block scope. Either way, my unedited answer works fine. – wsanville Apr 25 '12 at 14:22
  • Eww! I prefer to do it cleaner still: `for(var i = 1; i <= 5; i++){createWidget(i);}` and move the entire jQuery statement into `createWidget` or whatever. Why create an anonymous function every iteration? – Lee Kowalkowski Apr 25 '12 at 15:23
  • Why create an anonymous function every iteration? You do that to capture the value of `i` each time. That's what a closure does. – wsanville Apr 25 '12 at 15:37