Javascript jQuery scroll()检测用户何时停止滚动

Javascript jQuery scroll()检测用户何时停止滚动,javascript,jquery,scroll,jquery-events,Javascript,Jquery,Scroll,Jquery Events,好吧 $(window).scroll(function() { $('.slides_layover').removeClass('showing_layover'); $('#slides_effect').show(); }); 根据我的理解,我可以判断何时有人在滚动。因此,我试图找出当有人停下来时如何接住。从上面的示例中,您可以看到,在滚动发生时,我正在从一组元素中删除一个类。但是,我想在用户停止滚动时重新打开该类 $(window).scroll((e) ->

好吧

$(window).scroll(function()
{
    $('.slides_layover').removeClass('showing_layover');
    $('#slides_effect').show();
});
根据我的理解,我可以判断何时有人在滚动。因此,我试图找出当有人停下来时如何接住。从上面的示例中,您可以看到,在滚动发生时,我正在从一组元素中删除一个类。但是,我想在用户停止滚动时重新打开该类

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

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

  currentScrollTop = $(this).scrollTop()
)

这样做的原因是,我打算在页面滚动时进行一次中途停留展示,以给页面一种我正在尝试处理的特殊效果。但是我在滚动时试图删除的一个类与该效果冲突,因为它在某种程度上是一种透明效果。

您可以设置一个间隔,大约每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);
我还没有测试过这段代码,但原理应该是可行的。

使用jQuery throttle/debounce 这是解决类似问题的好办法

第二个参数是“at_begin”标志。在这里,我展示了如何在“滚动开始”和“滚动完成”时执行代码

使用Lodash 正如Barry p所建议的,或者也有一个去盎司,每个都有稍微不同的API

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

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

Rob W建议我在stack上查看另一篇文章,这篇文章本质上与我原来的文章相似。通过阅读,我发现了一个指向网站的链接:

这实际上帮助我很好地解决了我的问题,在为我自己的需要做了一点调整之后,但总的来说,它帮助我摆脱了很多废话,并为我节省了大约4个小时的时间

鉴于这篇文章似乎有一些优点,我想我会回来并提供最初在上面提到的链接上找到的代码,以防作者决定改变网站的方向并最终删除链接

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

})();
更新

我编写了一个扩展来增强jQuery在-事件处理程序上的默认
。它将一个或多个事件的事件处理程序函数附加到所选元素,并在给定时间间隔内未触发事件时调用处理程序函数。如果您希望仅在延迟后(如调整大小事件等)启动回调,这将非常有用

检查github repo的更新非常重要

;(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));
或绑定-事件处理程序上的任何其他
一样使用它,但可以将一个额外参数作为最后一个参数传递:

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

(本演示使用了
调整大小
而不是
滚动
,但谁在乎呢?!)


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

我同意上面的一些评论,即侦听超时不够准确,因为当您停止移动滚动条足够长的时间而不是停止滚动时,会触发超时。我认为更好的解决方案是倾听用户在开始滚动时松开鼠标(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 
    });
});

可以在

中看到it工作的一个例子,这是我以前使用过的。 基本上,您看起来像是在保留对最后一个
scrollTop()
的引用。 超时清除后,检查当前的
scrollTop()
,如果它们相同,则完成滚动

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

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

  currentScrollTop = $(this).scrollTop()
)
请检查一下电话号码


对于那些仍然需要的人,这里是解决方案

$(函数(){
变量t;
document.addEventListener('scroll',函数(e){
清除超时(t);
checkScroll();
});
函数checkScroll(){
t=设置超时(函数(){
警报(“完成滚动”);
},500);/*您可以增加或减少计时器*/
}
});这应该可以:

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

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

以下是您可以处理此问题的方法:

var scrollStop=函数(回调){
如果(!callback | | typeof callback!=“function”)返回;
变异系数;
window.addEventListener('scroll',函数(事件){
窗口清除超时(IsCrolling);
isScrolling=setTimeout(函数(){
回调();
}, 66);
},假);
};
滚动停止(函数(){
log('滚动已停止');
});

标题

<
<
<
<
<
<
<
<
<
<<
<<
<<
<<
<<
<
<
<
<<
<<
<<<<
<<<<<<<
<<<<<<<<<
<<<<<<<<<<<
<<<<<<<<<<<
<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<










<
<
<
<
<
<
<
<
<
<<
<<
<<
<<
<<
<
<
<
<<
<<
<<<<
<<<<<<<
<<<<<<<<<
<<<<<<<<<<<
<<<<<<<<<<<
<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<









<
<
<
<
<
<
<
<
<
<<
<<
<<
<<
<<
<
<
<
<<
<<
<<<<
<<<<<<<
<<<<<<<<<
<<<<<<<<<<<
<<<<<<<<<<<
<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<







<
<
<
<
<
<
<
<
<
<
<<
<<
<<
<<
<<
<
<
<
<<
<<
<<<<<
<<<<<<
<<<<<<<<<
<<<<<<<<<<<<
<<<<<<<<<<<
<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<>









<
<
<
<
<
<
<
<
<
<<
<<
<<
<<
<<
<
<
<
<<
<<
<<<<
<<<<<<<
<<<<<<<<<
<<<<<<<<<<<
<<<<<<<<<<<
<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<







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

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

  currentScrollTop = $(this).scrollTop()
)
$(document).on("scrollstop",function(){
  alert("Stopped scrolling!");
});
var Timer;
$('.Scroll_Table_Div').on("scroll",function() 
{
    // do somethings

    clearTimeout(Timer);
    Timer = setTimeout(function()
    {
        console.log('scrolling is stop');
    },50);
});
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.
}
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
}))