Skip to content Skip to sidebar Skip to footer

Javascript Variable Scope Inside For Loop

How do I maintain access to the i variable inside my for loop below? I'm trying to learn, not just get the answer, so a bit of explanation would be very helpful. Thank you! var el,

Solution 1:

All of your callbacks share the same i variable. When the event handler actually runs, i is after the end of the array.

You need to wrap the loop body in a self-invoking function that takes i as a parameter. This way, each iteration will get its own, unchanging, i variable.

For example:

for (var i = 0; i < statesPolyStrings.length; i++) {
    (function(i) {
        ...
    })(i);
}

Solution 2:

The trick with self-invoking functions works fine: it creates a new scope (maybe google for 'scope in functions javascript') and therefore handles i as a different variable and delivers the right value to your event listener callback function.

But you actually don't need to find your element again with jQuery as you already assigned an event listener to it and inside your function you have a reference to your element with this.

And as you're using jQuery anyhow, it's then easy to find the correct index (your i) of statesPolyObjects with $.inArray() passing the id of your element and the statesPolyStrings array (assuming you're dealing with unique IDs. If not, $("#"+statesPolyStrings[i]) would also fail, as it takes the first it finds).

var el;

for (var i = 0, len = statesPolyStrings.length; i < len; i++) {
    el = document.getElementById(statesPolyStrings[i]);

    google.maps.event.addDomListener(el, 'mouseover', function(event) {
        $(this).addClass("highlight");
        statesPolyObjects[$.inArray(this.id, statesPolyStrings)].
            setOptions({ strokeWeight: '2' });
    });
}

If you still want to stick with the self-invoking function you should anyhow change the following line:

("#"+statesPolyStrings[i]).addClass("highlight");

to

$(this).addClass("highlight");

If you're not familiar enough with this and events you might want to read this article: http://www.sitepoint.com/javascript-this-event-handlers/

You might have noticed that I also wrote the argument event inside the anonymous callback function. Try to console.log this event you get delivered for free with any event listener callback function and explore all the other things you have access to. For example, you can find the actual element you clicked on with event.target (as the actual mouseover might have happened to a child of your element). So:

google.maps.event.addDomListener(el, 'mouseover', function(event) {
    console.log(event);
    ...

and open the console of your browser to see what event delivers...

Be aware though that google.maps.event.addDomListener passes something different then document.body.addEventListener and there is also a difference between browsers. jQuery.on() for example also delivers some different things in the event object, but there you can at least count on the same data in all browsers.

Solution 3:

for (var i = 0; i < statesPolyStrings.length; i++) {
    (function(i){
        google.maps.event.addDomListener(document.getElementById(statesPolyStrings[i]), 'mouseover', function() {
        $("#"+statesPolyStrings[i]).addClass("highlight");
        statesPolyObjects[i].setOptions({ strokeWeight: '2' });
        });
    })(i)
}

Post a Comment for "Javascript Variable Scope Inside For Loop"