user1282226
user1282226

Reputation:

JavaScript: For loop issue

I have 3 .a and a function that is supposed to alert the number [0, 1 or 2] .a belongs to when it is mouseover-ed:

​function a(){
    for(var c=0; c<3; c++){
        alert(c);
        $('.a:eq('+c+')').mouseover(function(){alert(c)});       
    }

}

When I execute it, the first alert(c) is triggered three times and the message is "0", "1" ,"2" respectively, as expected.

However, when mouseover .a, no matter which .a it is, it alerts "3".

http://jsfiddle.net/f6tQn/

I would appreciate if someone can explain why this is happening and provide a solution.

Upvotes: 1

Views: 146

Answers (4)

JKirchartz
JKirchartz

Reputation: 18042

Because c=3.

Your loop adds 1 to C each time it runs, C still equals 3 after the code is run, giving your alerts the value of C, which is 3.

Your example can be completely rewritten and simplified as

$('.a').mouseover(function(){
    alert($(this).index());
});

this will generate an alert for all elements with class a, and give their position in the array that $('.a') generates.

BTW: JSLint errors when putting functions in a loop, if you want to keep JSLint happy check out this Question

Upvotes: 4

Robert Beuligmann
Robert Beuligmann

Reputation: 1444

C is bound to the same physical location in memory, so when you run the alert with the mouseover it is pulling from the last set value which is 3.

Your actually creating a 'closure' over the variable c if you feel like doing some deeper reading on the subject.

Try this

function a(){
    for(var c=0; c<3; c++){
        alert(c);
        (function(a){
           $('.a:eq('+a+')').mouseover(function(){alert(a)});
        })(c);      
    }

}

Upvotes: 1

gen_Eric
gen_Eric

Reputation: 227310

This is happening because each of your mouseover functions are using the same value of c, which is 3 when the loop is done.

You need to make a closue to "capture" the value of c for each iteration.

function a(){
    for(var c=0; c<3; c++){
        alert(c);
        var func = function(c){
            return function(){ // closes around the current value of "c"
                alert(c);
            };
        };
        $('.a:eq('+c+')').mouseover(func(c));       
    }
}

DEMO: http://jsfiddle.net/vDbu3/

Upvotes: 1

MushinNoShin
MushinNoShin

Reputation: 4886

You're getting caught by function scoped variables in javascript. This is a big javascript gotcha.

You need to create a function that does what you want the body of your for loop to do and takes c as a parameter.

Upvotes: 1

Related Questions