Как я могу отличить ручную прокрутку (через колесико мыши/полосу прокрутки) из свитка Javascript/jQuery?
UPDATE:
Вот пример jsbin, демонстрирующий проблему.
ОБНОВЛЕНИЕ 2:
И здесь фиксированная версия благодаря fudgey.
В принципе, у меня есть следующий javascript, который прокручивает окно до привязки на странице:
// get anchors with href 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 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;
});
Он отлично работает...... пока я не попытаюсь вручную прокрутить окно. Когда прокрутка или колесико прокручивается, мне нужно остановить текущую анимацию прокрутки... но я не уверен, как это сделать.
Это, наверное, моя отправная точка...
$(window).scroll(e){
if(IsManuallyScrolled(e)){
$("html,body").stop();
}
}
... но я не уверен, как закодировать функцию IsManuallyScrolled
. Я проверил e
(объект event
) в консоли Google Chrome и AFAIK не существует способа различать прокрутку вручную и прокрутку jQuery animate()
.
Как я могу различать ручную прокрутку и одну, вызванную через функцию jQuery $.fn.animate
?
Ответы
Ответ 1
Попробуйте эту функцию:
$('body,html').bind('scroll mousedown wheel DOMMouseScroll mousewheel keyup', function(e){
if ( e.which > 0 || e.type == "mousedown" || e.type == "mousewheel"){
$("html,body").stop();
}
})
Кроме того, вы видели этот учебник?
Обновление. Современные браузеры теперь используют "wheel" в качестве события, поэтому я включил его в код выше.
Ответ 2
У меня была одна и та же проблема несколько дней назад. Вы не должны использовать функцию анимации jquery, если хотите получить этот результат, вам нужно смоделировать анимацию с помощью функции опроса.
Я сделал этот класс, который должен обеспечивать плавный прокрутки, когда вызывается ScrollDown.slow().
ScrollDown.current=$(window).scrollTop();
ScrollDown.lastValue;
ScrollDown.lastType;
ScrollDown.enabled=true;
ScrollDown.custom=function(value,rate){ //let 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 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(){}
Итак, если вы должны были вызвать ScrollDown.slow('bottom'), он начнет медленно прокручиваться до тех пор, пока он не достигнет нижней части вашей страницы, если вы не прокрутите вверх или вниз вручную, а затем остановится.
Ответ 3
Вы можете установить переменную, чтобы указать, что ваш вызов для анимации был активным, а затем проверить эту переменную внутри обработчика прокрутки.
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();
}