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]+'"]');
});
};
- 338,112
- 86
- 474
- 445
- 119
- 8
-
1Kinda 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 Answers
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.
- 479,566
- 201
- 878
- 984
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 );
};
- 1,226
- 8
- 17
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));
- 15,582
- 10
- 47
- 64