views:

366

answers:

2

UPDATE:

Here is a jsbin example demonstrating the problem.

UPDATE 2:
And here is the fixed version thanks to fudgey.


Basically, I have the following javascript which scrolls the window to an anchor on the page:

 // get anchors with href's that start with "#"
 $("a[href^=#]").live("click", function(){
     var target = $($(this).attr("href"));
     // if the target exists: scroll to it...
     if(target[0]){
         // If the page isn't long enough to scroll to the target's position
         // we want to scroll as much as we can. This part prevents a sudden 
         // stop when window.scrollTop reaches its maximum.
         var y = Math.min(target.offset().top, $(document).height() - $(window).height());
         // also, don't try to scroll to a negative value...
         y=Math.max(y,0);
         // OK, you can scroll now...
         $("html,body").stop().animate({ "scrollTop": y }, 1000);
     }
     return false;
 });

It works perfectly......until I manually try to scroll the window. When the scrollbar or mousewheel is scrolled I need to stop the current scroll animation...but I'm not sure how to do this.

This is probably my starting point...

$(window).scroll(e){
    if(IsManuallyScrolled(e)){
        $("html,body").stop();
    }
} 

...but I'm not sure how to code the IsManuallyScrolled function. I've checked out e (the event object) in Google Chrome's console and AFAIK there is not way to differentiate between a manual scroll and jQuery's animate() scroll.

How can I differentiate between a manual scroll and one called via jQuery's $.fn.animate function?

+3  A: 

Try this function:

$('body,html').bind('scroll mousedown DOMMouseScroll mousewheel keyup', function(e){
 if ( e.which > 0 || e.type == "mousedown" || e.type == "mousewheel"){
  $("html,body").stop();
 }
})

Also, did you see this tutorial?

fudgey
THANK YOU! No, I didn't see the tutorial, thanks for that too. Here is an updated [JSBin example](http://jsbin.com/eqafi/4) with your fix
David Murdoch
Oh, and why use DOMMouseScroll? Does "scroll" !== "DomMouseScroll"?
David Murdoch
`DOMMouseScroll` is for Firefox only (ref: http://www.quirksmode.org/dom/events/scroll.html)
fudgey
So jQuery doesn't map DOMMouseScroll to scroll for us?
David Murdoch
Oddly enough, no, so to support it you'll need to use the plugin (http://plugins.jquery.com/project/mousewheel)
fudgey
Just in case you are interested, I used some of your code to help someone with this question (http://stackoverflow.com/questions/2896869/jquery-changing-css-on-navigation-when-div-scrolls-into-view/2898109#2898109)... here is that demo (http://jsfiddle.net/m2zQE/) :) Cheers!
fudgey
A: 

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();  
}  
John Fisher
This won't work because window.IsAutoScrolling will always be true until the scrolling stops...at which point we no longer care that the window is auto scrolling. The problem is detecting what is calling the scroll DURING the animate scroll; jquery or the user.
David Murdoch