Search code examples
javascriptjqueryjquery-waypoints

Loop of Waypoint, attribut undefined after quit loop


Needed some waypoints stuff, I tried to make a loop which can help me to properly do it. (I tried before without loop, but make somethink like 8 / 10 var, this isn't really fun)

Actually, my code seems to be good, exept the fact than Waypoint doesn't work when I scroll.

btn-selected & btn-transparent are css class which help me to show to the user where he is on the page.

Here my code.

// array of id, my left menu
var tableMenu = new Array("#left-menu-top", "#left-menu-evo-details", "#left-menu-details-accordeon", "#left-menu-awesome", "#left-menu-prog-rerun", "#left-menu-features", "#left-menu-timeline", "#left-menu-upgrade");
// array of id, content section
var tableSection = new Array("top", "evo-details", "details-accordeon", "awesome", "prog-rerun", "features", "timeline", "upgrade");
// waypoint object array
var WaypointArray = {};
// array of offset
var OffsetWaypointArray = new Array("-50", "55", "55", "55", "55", "55", "55", "0");

function clearAllButtons() {

    for(value in tableMenu) {
        $(tableMenu[value]).removeClass("btn-selected");
        $(tableMenu[value]).addClass("btn-tranparent");
    }
}

function replaceClass(idLeftMenu) {
    clearAllButtons();
    $(idLeftMenu).removeClass("btn-tranparent");
    $(idLeftMenu).addClass("btn-selected");
}

$(document).ready(function() {
    console.log('activated');
    for(var count=0; count < tableMenu.length; count++) {
        WaypointArray[count] = new Waypoint({
            element: document.getElementById(tableSection[count]),
            handler: function(direction) {
                clearAllButtons(),
                replaceClass(tableMenu[count]),
                console.log("you reached waypoint : "+tableSection[count]+" to : "+direction);
            },
            offset: OffsetWaypointArray[count]
        });
        console.log('counted '+count);
        //OffsetWaypointArray = {WaypointArray[count]};
    }

    //for(var count = 0; count < tableMenu.length; count++) {
    //  console.log(WaypointArray[count]);
    //}
});

After some scroll, console log give me that.

activated
scripts.js:32 you reached waypoint : top to : down
scripts.js:36 counted 0
scripts.js:32 you reached waypoint : evo-details to : down
scripts.js:36 counted 1
scripts.js:36 counted 2
scripts.js:36 counted 3
scripts.js:36 counted 4
scripts.js:36 counted 5
scripts.js:36 counted 6
scripts.js:36 counted 7
2scripts.js:32 you reached waypoint : undefined to : down
scripts.js:32 you reached waypoint : undefined to : up
scripts.js:32 you reached waypoint : undefined to : down
scripts.js:32 you reached waypoint : undefined to : up
2scripts.js:32 you reached waypoint : undefined to : down
scripts.js:32 you reached waypoint : undefined to : up

So it seems after quit the loop^, Waypoint are not defined anymore. (Cause whereever I am when I refresh the page, the Waypoint work, and it show me at which page I am, but if I scroll, then I got errors)

Thanx for your help


Solution

  • This is a classic closure problem in JavaScript. The count variable you're using for the loop doesn't get captured at its current value when the asynchronous handler function gets run at a later date. Put another way, just because count was 4 when you created the waypoint doesn't mean it's value is 4 when it gets executed. In your example, count is going to be 8 when all your handlers execute and your array has nothing at index 8.

    MDN has a decent article on closures that may help as a jumping off point.