Reputation: 5553
I have a very long page broken up into <section>
tags. There is fixed position navigation that will scroll up and down the page. I need each press of the 'down' button to scroll the next <section>
to the top of the page. Same goes for the 'up' button, it should scroll the previous <section>
to the top of the page. I don't want to have to include an instance of the navigation in each section with specified scrollTo function. I would rather it be more universal. If there were a link in each section, it would be simpl. However, the navigation is position:fixed, so I can't use .next() or .closest(). I'm thinking I have to index the number of sections and step through them?
This works only on the first press:
$('#scrollWindowUp').click(function(e){
e.preventDefault();
$('html, body').animate({ scrollTop: ($('section').next().offset().top)},500);
});
$('#scrollWindowDown').click(function(e){
e.preventDefault();
$('html, body').animate({ scrollTop:($('section').prev().offset().top)},500);
});
Here is a fiddle
Each section is the height of the viewport, so you only see one at a time. I am just grabbing the $('window').height();
and applying it to the <section>
so they fill the window. I've tried using that calculation to do the scrolling, but it is always off a little.
Upvotes: 0
Views: 2114
Reputation: 109
Storing the current index or element may have undesired effects if the user scrolls the page themselves as it will jump to the next section when they last clicked on#scrollWindowDown rather than the next section on screen.
To allow the buttons to scroll from the current section regardless of whether the user has scrolled or not you'll need to calculate which section is currently visible.
function getCurrentSection () {
var cutoff = $(window).scrollTop();
var curIndex = 0;
for(var index = 0; index < $('section').length; index++){
if ($('section').eq(index).offset().top >= cutoff) {
curIndex = index;
break;
}
}
return curIndex;
};
$('#scrollWindowUp').click(function(e){
e.preventDefault();
var curIndex = getCurrentSection();
if (curIndex === 0) { return; }
$('html, body').animate({ scrollTop: ($('section').eq(curIndex-1).offset().top - 1)},500);
});
$('#scrollWindowDown').click(function(e){
e.preventDefault();
var curIndex = getCurrentSection();
if (curIndex === $('section').length) { return; }
var cutoff = $(window).scrollTop();
if ($('section').eq(curIndex).offset().top !== cutoff+1) { curIndex = curIndex-1; } /* Check if the current section is at the top of the page or has been scrolled */
$('html, body').animate({ scrollTop: ($('section').eq(curIndex+1).offset().top - 1)},500);
});
Upvotes: 1
Reputation: 1638
You need to set to a global var to remember which element you're at. Each time you go $('section')
, it's gonna grab the first element in the list.
var $section = $('section').first();
$('#scrollWindowUp').click(function(e){
e.preventDefault();
if ($section.is('section:last')) {
return;
}
$section = $section.next();
scroll();
});
$('#scrollWindowDown').click(function(e){
e.preventDefault();
if ($section.is('section:first')) {
return;
}
$section = $section.prev();
scroll();
});
function scroll() {
$('html, body').animate({ scrollTop: ($section.offset().top)},500);
}
Upvotes: 2