Reputation: 2506
Aiming to do something similar to this where the page jumps to anchors on the page when you scroll down. I'm no expert with JQuery or JS in general (backend languages PHP and MySQL are my areas of preference) I grabbed a couple of scripts and put them together. There will be three anchors on the page, so it's meant to jump to the next one down when you scroll down and the next one up when you scroll up. However, when it scrolls to the second one it keeps scrolling past it even when I'm not still scrolling. This is the script:
var section = 1;
function scrollToAnchor(variable){
var aTag = $("a[name='"+ variable +"']");
$('html,body').animate({scrollTop: aTag.offset().top},'slow');
}
$(function(){
//Keep track of last scroll
var lastScroll = 0;
$(window).scroll(function(event){
//Sets the current scroll position
var st = $(this).scrollTop();
//Determines up-or-down scrolling
if (st > lastScroll && section < 3){
//Going down
section = section + 1;
scrollToAnchor('section'+section);
lastScroll = st;
} else if(st < lastScroll && section > 1){
//Going up
section = section - 1;
scrollToAnchor('section'+section);
lastScroll = st;
}
//Updates scroll position
lastScroll = st;
});
});
And the fiddle: http://jsfiddle.net/tBN64/4/
Upvotes: 2
Views: 2395
Reputation: 33
I have found some bugs using Spokey's answer, when the page scrolled too much we got a js error, so I added some checks: if the section is the last one, then we needn't raise its number, and the same for scrolling up.
I got this code, but changed this for sections, not anchors:
var current_section = 1;
var min_section = 1;
var max_section = $("section[name]").length;
$(window).mousewheel(function (event, delta) {
if (delta > 0) {
current_section = current_section - 1; //up
if (current_section < min_section) current_section = min_section;
$('body, html').stop().animate({
scrollTop: $('section[name="section' + current_section + '"]').offset().top - 100
}, 'slow');
} else if (delta < 0) {
current_section = current_section + 1; //down
if (current_section > max_section) current_section = max_section;
$('body, html').stop().animate({
scrollTop: $('section[name="section' + current_section + '"]').offset().top - 100
}, 'slow');
}
return false;
});
$('body, html').scroll(function(){ return false; }); // allow no scrolling
Upvotes: 1
Reputation: 10994
The reason is that when you scroll
the scroll event
is fired and then the animate
function is scrolling to the element, but that animated scroll itself will fire the scroll event again resulting in a loop.
I suggest you try a different approach. You can for example catch the mousewheel direction and use that to scroll to the next element.
Example using the jQuery Mousewheel Plugin https://github.com/brandonaaron/jquery-mousewheel
var current_section = 1;
$(window).mousewheel(function (event, delta) {
if (delta > 0) {
current_section = current_section - 1; //up
$('body, html').stop().animate({
scrollTop: $('a[name="section' + current_section + '"]').offset().top
}, 'slow');
} else if (delta < 0) {
current_section = current_section + 1; //down
$('body, html').stop().animate({
scrollTop: $('a[name="section' + current_section + '"]').offset().top
}, 'slow');
}
return false;
});
Fiddle: http://jsfiddle.net/tBN64/6/ (the above code is at the end)
NOTE: This code does not verify if there is a next section
, so if you scroll to much it will throw an error. You need to make sure the next element exists / if it doesn't don't animate to it. (see console for errors, usually if you press F12 in your browser)
Upvotes: 2
Reputation: 3103
There are more problems in your script. First - I think you need to prevent the default behavior of the scroll event, otherwise it will scroll, and you do not want that, as you want to animate scroll yourself.
event.preventDefault()
could help and also a return false;
at the end of the function.
Then the problem is, that the scroll event is not triggered once, but more times with one mouse scroll. You somehow need to prevent this, as otherwise it happens, that the scroll begins, then you animation starts, but the scroll is still going on, it passes Section 2, and is triggered again and again..
Maybe this script could help - it makes a new event scrollStopped
:
jQuery - bind event on Scroll Stop
Generally I would advise you rather to search for a script that does this behavior, becasue programming it yourself can bring you to a lot of problems that other users may have fixed in the past in their plugins.
Upvotes: 1