Reputation: 28368
I'm trying to assign some scrolling destinations for a menu for my one page application, the idea of this script is to prevent myself from repeating the same code over and over, but it's not quite working out the way I want it to.
Basically what happens is that destinations[i]
becomes undefined and therefore I cannot access .dest
of it. When I try just to console log destinations[i]
I do get the desired result, but when I then go to click the buttons I can't scroll to anything since nothing is defined as the .offset
value.
Why doesn't the value of destinations[i]
remain after the loop and what can I do to make this work as intended?
var destinations = [
{class: '.home', dest: $('html, body')},
{class: '.lunch', dest: $('#menu-wrapper')},
{class: '.catering', dest: $('#catering-wrapper')},
{class: '.renting', dest: $('#renting-wrapper')},
{class: '.karaoke', dest: $('#karaoke-wrapper')},
{class: '.contact', dest: $('#site-footer')}
],
destLength = destinations.length,
i;
for (i = 0; i < destLength; i++) {
$(destinations[i].class + ' a').on('click', function() {
$('html, body').stop().animate({
scrollTop: destinations[i].dest.offset().top
}, 1000);
});
}
Upvotes: 0
Views: 35
Reputation: 16726
use functions, they have the scope you need:
var destinations = [
{"class": '.home', dest: $('html, body')},
{"class": '.lunch', dest: $('#menu-wrapper')},
{"class": '.catering', dest: $('#catering-wrapper')},
{"class": '.renting', dest: $('#renting-wrapper')},
{"class": '.karaoke', dest: $('#karaoke-wrapper')},
{"class": '.contact', dest: $('#site-footer')}
];
destinations.forEach(function(dest, i){
$(dest['class'] + ' a').on('click', function() {
$('html, body').stop().animate({
scrollTop: dest.dest.offset().top
}, 1000);
});
});
forEach() also leaves no extra vars hanging around, gives you an index for var free, doesn't need a length, and looks a little cleaner to boot.
edit: added old-ie-safe prop access for "class", which is a reserved word in JS...
Upvotes: 2
Reputation: 1244
As @dandavis suggested, foreach()
seems more logical here, but for your code, when you loop until destLength
it gives you the number of elements in destinations[]
, but elements numbering starts from 0, so you should use destLength-1
var destinations = [
{class: '.home', dest: $('html, body')},
{class: '.lunch', dest: $('#menu-wrapper')},
{class: '.catering', dest: $('#catering-wrapper')},
{class: '.renting', dest: $('#renting-wrapper')},
{class: '.karaoke', dest: $('#karaoke-wrapper')},
{class: '.contact', dest: $('#site-footer')}
],
destLength = destinations.length,
i;
for (i = 0; i < (destLength-1); i++) {
$(destinations[i].class + ' a').on('click', function() {
$('html, body').stop().animate({
scrollTop: destinations[i].dest.offset().top
}, 1000);
});
}
Upvotes: 0
Reputation: 489
I can't say for sure without seeing the surrounding code, but if you have the var
in front of the declaration of destinations
and it's inside of the loop, then destinations
is deleted as soon as the loop is executed. See What is the purpose of the var keyword and when to use it (or omit it)?
Upvotes: 0