检测用户何时停止滚动

好吧。

$(window).scroll(function()
{
$('.slides_layover').removeClass('showing_layover');
$('#slides_effect').show();
});

I can tell when someone is scrolling from what I understand. So with that I am trying to figure out how to catch when someone has stopped. From the above example you can see I am removing a class from a set of elements while the scrolling is occurring. However, I want to put that class back on when the user stops scrolling.

这是因为我打算在页面滚动时进行一个中转显示,以给页面一个我正在尝试的特殊效果。但是我在滚动时试图删除的一个类与这种效果相冲突,因为它在某些性质上具有透明性效果。

227731 次浏览

你可以设置一个间隔,每隔500毫秒左右,如下所示:

var curOffset, oldOffset;
oldOffset = $(window).scrollTop();
var $el = $('.slides_layover'); // cache jquery ref
setInterval(function() {
curOffset = $(window).scrollTop();
if(curOffset != oldOffset) {
// they're scrolling, remove your class here if it exists
if($el.hasClass('showing_layover')) $el.removeClass('showing_layover');
} else {
// they've stopped, add the class if it doesn't exist
if(!$el.hasClass('showing_layover')) $el.addClass('showing_layover');
}
oldOffset = curOffset;
}, 500);

我还没有测试过这个代码,但是这个原理应该可以工作。

Using jQuery throttle / debounce

JQuery deounce 是一个很好的解决这类问题的方法

$(window).scroll($.debounce( 250, true, function(){
$('#scrollMsg').html('SCROLLING!');
}));
$(window).scroll($.debounce( 250, function(){
$('#scrollMsg').html('DONE!');
}));

第二个参数是“ at _ start”标志。在这里,我展示了如何在“滚动开始”和“滚动结束”执行代码。

使用 Lodash

正如巴里 P 建议,JsFiddle下划线浪荡也有一个脱脂,每个略有不同的 apis。

$(window).scroll(_.debounce(function(){
$('#scrollMsg').html('SCROLLING!');
}, 150, { 'leading': true, 'trailing': false }));


$(window).scroll(_.debounce(function(){
$('#scrollMsg').html('STOPPED!');
}, 150));

Rob W 建议我看看 Stack 上的另一篇文章,它和我最初的那篇文章基本相似。通过阅读,我发现了一个网站的链接:

Http://james.padolsey.com/javascript/special-scroll-events-for-jquery/

事实上,在我根据自己的需要做了一些调整之后,这个方法最终帮助我很好地解决了问题,但是总的来说,它帮助我摆脱了很多废话,并且为我节省了大约4个小时的时间来自己解决问题。

Seeing as this post seems to have some merit, I figured I would come back and provide the code found originally on the link mentioned, just in case the author ever decided to go a different direction with the site and ended up taking down the link.

(function(){


var special = jQuery.event.special,
uid1 = 'D' + (+new Date()),
uid2 = 'D' + (+new Date() + 1);


special.scrollstart = {
setup: function() {


var timer,
handler =  function(evt) {


var _self = this,
_args = arguments;


if (timer) {
clearTimeout(timer);
} else {
evt.type = 'scrollstart';
jQuery.event.handle.apply(_self, _args);
}


timer = setTimeout( function(){
timer = null;
}, special.scrollstop.latency);


};


jQuery(this).bind('scroll', handler).data(uid1, handler);


},
teardown: function(){
jQuery(this).unbind( 'scroll', jQuery(this).data(uid1) );
}
};


special.scrollstop = {
latency: 300,
setup: function() {


var timer,
handler = function(evt) {


var _self = this,
_args = arguments;


if (timer) {
clearTimeout(timer);
}


timer = setTimeout( function(){


timer = null;
evt.type = 'scrollstop';
jQuery.event.handle.apply(_self, _args);


}, special.scrollstop.latency);


};


jQuery(this).bind('scroll', handler).data(uid2, handler);


},
teardown: function() {
jQuery(this).unbind( 'scroll', jQuery(this).data(uid2) );
}
};


})();
$(window).scroll(function() {
clearTimeout($.data(this, 'scrollTimer'));
$.data(this, 'scrollTimer', setTimeout(function() {
// do something
console.log("Haven't scrolled in 250ms!");
}, 250));
});

更新

我编写了一个 分机来增强 jQuery 的默认 on事件处理程序。它将一个或多个事件的事件处理程序函数附加到选定的元素,如果在给定的时间间隔内没有触发事件,则调用处理程序函数。如果希望仅在延迟(如调整大小事件等)之后才激发回调,则此选项非常有用。

检查 github-repo 是否有更新非常重要!

Https://github.com/yckart/jquery.unevent.js

;(function ($) {
var on = $.fn.on, timer;
$.fn.on = function () {
var args = Array.apply(null, arguments);
var last = args[args.length - 1];


if (isNaN(last) || (last === 1 && args.pop())) return on.apply(this, args);


var delay = args.pop();
var fn = args.pop();


args.push(function () {
var self = this, params = arguments;
clearTimeout(timer);
timer = setTimeout(function () {
fn.apply(self, params);
}, delay);
});


return on.apply(this, args);
};
}(this.jQuery || this.Zepto));

像使用任何其他 onbind事件处理程序一样使用它,除了您可以将一个额外的参数作为最后一个传递:

$(window).on('scroll', function(e) {
console.log(e.type + '-event was 250ms not triggered');
}, 250);

http://yckart.github.com/jquery.unevent.js/

(本演示使用 resize而不是 scroll,但谁在乎呢? !)

function scrolled() {
//do by scroll start
$(this).off('scroll')[0].setTimeout(function(){
//do by scroll end
$(this).on('scroll',scrolled);
}, 500)
}
$(window).on('scroll',scrolled);

非常小的版本具有开始和结束的能力

我同意上面的一些评论,即监听超时是不够准确的,因为当你停止移动滚动条足够长的时间,而不是当你停止滚动时,就会触发。我认为一个更好的解决方案是监听用户一开始滚动鼠标就放开的情况:

$(window).scroll(function(){
$('#scrollMsg').html('SCROLLING!');
var stopListener = $(window).mouseup(function(){ // listen to mouse up
$('#scrollMsg').html('STOPPED SCROLLING!');
stopListner(); // Stop listening to mouse up after heard for the first time
});
});

它工作的一个例子可以在 这个 JSFiddle中看到

这是我以前用过的东西。 基本上你看到的是一个持有裁判到最后的 scrollTop()。 Once your timeout clears, you check the current scrollTop() and if they are the same, you are done scrolling.

$(window).scroll((e) ->
clearTimeout(scrollTimer)
$('header').addClass('hidden')


scrollTimer = setTimeout((() ->
if $(this).scrollTop() is currentScrollTop
$('header').removeClass('hidden')
), animationDuration)


currentScrollTop = $(this).scrollTop()
)

please check the 移动滚动停止事件

$(document).on("scrollstop",function(){
alert("Stopped scrolling!");
});

对于那些还需要这个的人来说,这就是解决办法

  $(function(){
var t;
document.addEventListener('scroll',function(e){
clearTimeout(t);
checkScroll();
});
      

function checkScroll(){
t = setTimeout(function(){
alert('Done Scrolling');
},500); /* You can increase or reduse timer */
}
});

这应该会奏效:

var Timer;
$('.Scroll_Table_Div').on("scroll",function()
{
// do somethings


clearTimeout(Timer);
Timer = setTimeout(function()
{
console.log('scrolling is stop');
},50);
});

你可以这样处理:

    var scrollStop = function (callback) {
if (!callback || typeof callback !== 'function') return;
var isScrolling;
window.addEventListener('scroll', function (event) {
window.clearTimeout(isScrolling);
isScrolling = setTimeout(function() {
callback();
}, 66);
}, false);
};
scrollStop(function () {
console.log('Scrolling has stopped.');
});
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.&l
t;br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<b
r>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>
</body>
</html>

这将使用全局计时器在1毫秒后检测滚动停止(或更改它) :

var scrollTimer;


$(window).on("scroll",function(){
clearTimeout(scrollTimer);
//Do  what you want whilst scrolling
scrollTimer=setTimeout(function(){afterScroll()},1);
})


function afterScroll(){
//I catched scroll stop.
}

ES6风格与检查滚动启动也。

function onScrollHandler(params: {
onStart: () => void,
onStop: () => void,
timeout: number
}) {
const {onStart, onStop, timeout = 200} = params
let timer = null


return (event) => {
if (timer) {
clearTimeout(timer)
} else {
onStart && onStart(event)
}
timer = setTimeout(() => {
timer = null
onStop && onStop(event)
}, timeout)
}
}

用法:

yourScrollableElement.addEventListener('scroll', onScrollHandler({
onStart: (event) => {
console.log('Scrolling has started')
},
onStop: (event) => {
console.log('Scrolling has stopped')
},
timeout: 123 // Remove to use default value
}))