Como posso diferenciar uma rolagem manual (via roda do mouse / barra de rolagem) de uma rolagem Javascript / jQuery?

ATUALIZAR:

Aqui está um exemplo jsbin demonstrando o problema.

ATUALIZAÇÃO 2:
E aqui está a versão corrigida graças ao fudgey .


Basicamente, eu tenho o seguinte javascript que rola a janela para uma âncora na página:

// 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; }); 

Funciona perfeitamente …… até eu manualmente tentar rolar a janela. Quando a barra de rolagem ou mousewheel é rolada eu preciso parar a animação de rolagem atual … mas não sei como fazer isso.

Este é provavelmente o meu ponto de partida …

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

… mas não sei como codificar a function IsManuallyScrolled . Eu verifiquei e (o object de event ) no console do Google Chrome e no AFAIK, não há como diferenciar entre uma rolagem manual e a rolagem animate() do jQuery animate() .

Como posso diferenciar entre uma rolagem manual e uma chamada pela function $.fn.animate do jQuery?

    Experimente esta 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(); } }) 

    Além disso, você viu este tutorial ?

    Atualização: navegadores modernos agora usam “wheel” como o evento, então incluímos no código acima.

    Eu tive o mesmo problema alguns dias atrás. Você não deveria estar usando a function animada do jquery se você quer obter aquele resultado, você tem que simular a animação usando uma function de busca.

    Eu fiz essa class que deve fornecer um scrolldown suave quando ScrollDown.slow () é chamado.

     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.currentScrollDown.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(){} 

    Então, se você fosse chamar ScrollDown.slow (‘bottom’), ele iria começar a rolar lentamente até chegar ao final da sua página, a menos que você rolasse para cima ou para baixo manualmente, então ele pararia.

    Você pode definir uma variável para indicar que sua chamada para animar estava ativa e, em seguida, verificar essa variável dentro do manipulador de rolagem.

     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(); }