jQuery滚动()检测用户停止滚动

好吧,这个..

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

我可以知道什么时候有人正在滚动我的理解。 所以,我正在试图找出有人停下来的时候该怎么抓。 从上面的例子中,你可以看到我正在滚动正在发生的一组元素中删除一个类。 但是,我想在用户停止滚动时重新放置该类。

原因是我打算在网页滚动的时候进行一个停留时间的显示,给页面一个我正在尝试的特殊效果。 但是,我正在试图去除的一个类,而滚动与这种效果的冲突,因为它对一些性质的透明度效应。

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

更新

我写了一个扩展来增强jQuery on事件处理器on的默认值。 它将一个或多个事件的事件处理函数附加到所选元素,并在给定时间间隔内未触发事件时调用处理函数。 如果您只想在延迟之后触发callback(如resize事件等),则此function非常有用。

检查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 -event处理程序一样使用它,除了可以将最后一个parameter passing给另一个参数:

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

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

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

使用jQuery油门/去抖动

对于这样的问题, jQuery去抖是一个不错的select。 jsFidlle

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

第二个参数是“at_begin”标志。 在这里我已经展示了如何在“滚动开始”和“滚动结束”中执行代码。

使用Lodash

正如Barry P所build议的, jsFiddle , 下划线或lodash也有反弹 ,每个apis略有不同。

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

Rob W suggected我在这里看到另外一个post,这本质上和我原来的post差不多。 哪个阅读,我发现一个网站的链接:

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

这实际上最终帮助我解决了我的问题,经过对自己的需求做了一点调整之后,但是总算帮了我很多忙,并且救了我大约4个小时。

看到这篇文章似乎有一些优点,我想我会回来,并提供原来在上面提到的链接find的代码,以防万一作者决定与网站不同的方向,并最终取消链接。

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

您可以设置一个间隔,每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); 

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

我同意上面的一些意见,听超时是不够准确的,因为当你停止移动滚动条足够长的时间,而不是停止滚动时会触发。 我认为一个更好的解决scheme是听用户放开鼠标(mouseup),只要他们开始滚动:

 $(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中可以看到它的一个例子

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

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

好的,这是我以前用过的东西。 基本上你看起来像是最后一个scrollTop() 。 一旦你的超时清除,你检查当前的scrollTop() ,如果他们是相同的,你已经完成滚动。

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

请检查jquery mobile scrollstop事件

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