Here is a jsbin example demonstrating the problem.
UPDATE 2:
And here is the fixed version thanks to fudgey.
Bas
You could set a variable to indicate that your call to animate was active, then check that variable inside the scroll handler.
window.IsAutoScrolling = true;
$("html,body").stop().animate({ "scrollTop": y }, 1000);
// Do something to set IsAutoScrolling = false, when the animation is done.
$(window).scroll(e){
if(!window.IsAutoScrolling){
$("html,body").stop();
}
I had your same issue some a few days ago.You shouldn't be using jquery's animate function if you want to obtain that result, you have to simulate the animation using a polling function.
I made this class which is supposed to provide a smooth scrolldown when ScrollDown.slow() is called.
ScrollDown.current=$(window).scrollTop();
ScrollDown.lastValue;
ScrollDown.lastType;
ScrollDown.enabled=true;
ScrollDown.custom=function(value,rate){ //let's say value==='bottom' and rate=10
if(value==='bottom'){
value=$(document).height()-$(window).height();
}
ScrollDown.current=$(window).scrollTop();
ScrollDown.lastValue=value;
(function poll(){
setTimeout(function(){
var prev=$(window).scrollTop(); //This is the critical part
/*I'm saving again the scroll position of the window, remember
10 ms have passed since the polling has started
At this rate, if the user will scroll up for down pre!==ScrollDown.current
And that means I have to stop scrolling.*/
ScrollDown.current++; //increasing the scroll variable so that it keeps scrolling
$(window).scrollTop(ScrollDown.current);
if(ScrollDown.current<ScrollDown.lastValue && ScrollDown.enabled){
//ScrollDown.current<ScrollDown.lastValue basically checks if it's reached the bottom
if(prev!==ScrollDown.current-1){
/*I'm checking if the user
scrolled up or down while the polling has been going on,
if the user scrolls up then prev<ScrollDown.current-1,
if the user scrolls down then prev>ScrollDown.current-1
and at the next poll() the scrolling will stop
because ScrollDown.enabled will bet set to false by ScrollDown.stop()*/
ScrollDown.stop();
}
poll();
}
},rate);
})();
};
ScrollDown.stop=function(){
ScrollDown.enabled=false;
};
ScrollDown.continue=function(){
ScrollDown.enabled=true;
switch (ScrollDown.lastType){
case "fast":
ScrollDown.fast(ScrollDown.lastValue);
break;
case "normal":
ScrollDown.normal(ScrollDown.lastValue);
break;
case "slow":
ScrollDown.slow(ScrollDown.lastValue);
break;
}
};
ScrollDown.fast=function(value){
if(!ScrollDown.enabled){
ScrollDown.continue();
}else{
ScrollDown.lastType='fast';
ScrollDown.custom(value,1);
}
};
ScrollDown.normal=function(value){
if(!ScrollDown.enabled){
ScrollDown.continue();
}else{
ScrollDown.lastType='normal';
ScrollDown.custom(value,10);
}
};
ScrollDown.slow=function(value){
if(!ScrollDown.enabled){
ScrollDown.continue();
}else{
ScrollDown.lastType='slow';
ScrollDown.custom(value,50);
}
};
function ScrollDown(){}
So if you were to call ScrollDown.slow('bottom') it would start scrolling slowly till it reaches the bottom of your page unless you scroll up or down manually, then it stops.
Try this function:
$('body,html').bind('scroll mousedown wheel DOMMouseScroll mousewheel keyup', function(e){
if ( e.which > 0 || e.type == "mousedown" || e.type == "mousewheel"){
$("html,body").stop();
}
})
Also, did you see this tutorial?
Update: Modern browsers now use "wheel" as the event, so I've included it in the code above.