1
var el = $('.container');
var anchors = new Array('jobs', 'portfolio', 'docs', 'interier', 'price');
for (var i = 0; i < anchors.length; i++) {
    el.on('click', 'a[href$="#'+anchors[i]+'"]', function (e) {
        e.preventDefault();
        console.log(anchors[i]);
        $.scrollTo('a[name="'+anchors[i]+'"]');
    });
};
Andy E
  • 338,112
  • 86
  • 474
  • 445
user2194521
  • 119
  • 8
  • 1
    Kinda offtopic: initializing arrays like var anchors=['a','b','c'] should be faster – DVM Mar 21 '13 at 10:05
  • possible duplicate of [Javascript closure inside loops - simple practical example](http://stackoverflow.com/questions/750486/javascript-closure-inside-loops-simple-practical-example) – Felix Kling Mar 21 '13 at 10:12
  • Wrong scope, i is not defined there. – Darin Kolev Mar 27 '13 at 23:41

3 Answers3

3

When you click that element, i will have been incremented to the value of anchors.length.

Your click handler has a reference to i.

An unresolved property lookup in JavaScript returns undefined.

It would be much easier to use this as a reference to the element. Otherwise, find a way to pass the value of i by value, not a direct reference to it.

alex
  • 479,566
  • 201
  • 878
  • 984
1

The reason you are getting undefined is because i is actually equal to 5. Take a look at this:

for ( var i = 0; i < 5; i++ ) {
    console.log( i );
}

Now after that loop has completed you would think that i would be undefined at this point in time because it should be local to the for loop. Unfortunately, this is not the case. A simple way to test this:

for ( var i = 0; i < 5; i++ ) {
    console.log( i );
}

console.log( i ) // Logs out 5;

Put simply, the i++ of the for loop gets executed after the truth test part, the i < 5 bit. So when i is equal to 4, the loop runs, and afterwards it gets incremented by i++, which sets the value of i to 5, which in turn fails the truth test.

So now that you know i is equal to 5, when you do the lookup in your anchors array, anchors[5] is undefined.

The reason this is important is because every time a click event fires, it will execute the cached value for i which is 5, and in turn, you will always log undefined

To fix this, we can create an alias to the value of i like so

var el = $('.container');
var anchors = new Array('jobs', 'portfolio', 'docs', 'interier', 'price');

for (var i = 0; i < anchors.length; i++) {

    // By passing the value to this self executing function,
    // it creates a new instance of the variable
    ( function ( index ) {
        el.on('click', 'a[href$="#'+anchors[index]+'"]', function (e) {
        e.preventDefault();
            console.log(anchors[index]);
            $.scrollTo('a[name="'+anchors[index]+'"]');
        });
    })( i );

};
whitneyit
  • 1,226
  • 8
  • 17
0

The variable i got the value of the last loop. If you want to access the anchor you can use this:

 console.log($(this).attr('href').substr(1));
Armin
  • 15,582
  • 10
  • 47
  • 64