1

Possible Duplicate:
Javascript closure inside loops - simple practical example

Can someone tell me why the value of 'i' in this code prints out the number 4? the loop only goes to 3, however it will print 'i = 4' inside of the menu_feedback div.

for(i=1; i<=3; i++){
    $('#file_button'+i).hover(function (){
        $('#menu_feedback').html('i = '+i+'<br/>');
    }, function(){
        $('#menu_feedback').html('');
    });
}

.

<button type="button" id="file_button1">Door 1</button>
<button type="button" id="file_button2">Door 2</button>
<button type="button" id="file_button3">Door 3</button>

<div id="menu_feedback"></div>
Community
  • 1
  • 1
M1Reeder
  • 692
  • 2
  • 7
  • 22

3 Answers3

5

Welcome to the world of closures.

Use this:

for(i=1; i<=3; i++) {
    (function(i) {
        // the code that depends on i
    })(i);
}
Niet the Dark Absol
  • 320,036
  • 81
  • 464
  • 592
3

This is a classic JavaScript problem. It's because the variable i in your hover function is the same variable from the loop. So, when the loop ends, i is 4, so it's 4 in the function.

Try something like this:

var hoverFunc = function(i){
    return function(){
        $('#menu_feedback').html('i = '+i+'<br/>');
    };
};
for(i=1; i<=3; i++){
    $('#file_button'+i).hover(hoverFunc(i), function(){
        $('#menu_feedback').html('');
    });
}

hoverFunc is a closure. It returns a function that "closes" around the value of i.

gen_Eric
  • 223,194
  • 41
  • 299
  • 337
2

Have a look at JavaScript closure inside loops – simple practical example for more information about the problem you are facing.

However, with jQuery event handlers, there is an other way to solve this, by passing the index as event data:

for(i=1; i<=3; i++){
    $('#file_button'+i).mouseenter({index: i}, function(event){
        $('#menu_feedback').html('i = '+ event.data.index + '<br/>');
    }).mouseleave(function(){
        $('#menu_feedback').html('');
    });
}
Community
  • 1
  • 1
Felix Kling
  • 795,719
  • 175
  • 1,089
  • 1,143