用户停止滚动时的事件

时间:2010-09-13 14:25:17

标签: javascript jquery javascript-events scroll

当用户滚动页面时,我想做一些花哨的jQuery东西。但我不知道如何解决这个问题,因为只有scroll()方法。

有什么想法吗?

8 个答案:

答案 0 :(得分:66)

您可以使scroll()每次用户滚动时都会被覆盖超时。这样,当他在脚本运行一定时间后停止运行,但如果他在此期间滚动,计数器将重新开始,脚本将等到他再次完成滚动。

<强>更新

因为这个问题再次得到了一些动作,我想我也可以用jQuery扩展来更新它,添加scrollEnd事件

// extension:
$.fn.scrollEnd = function(callback, timeout) {          
  $(this).scroll(function(){
    var $this = $(this);
    if ($this.data('scrollTimeout')) {
      clearTimeout($this.data('scrollTimeout'));
    }
    $this.data('scrollTimeout', setTimeout(callback,timeout));
  });
};

// how to call it (with a 1000ms timeout):
$(window).scrollEnd(function(){
    alert('stopped scrolling');
}, 1000);
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>

<div style="height: 200vh">
  Long div
</div>

答案 1 :(得分:58)

这是一个使用setTimeout在用户停止滚动时触发函数的简单示例:

(function() {        
    var timer;
    $(window).bind('scroll',function () {
        clearTimeout(timer);
        timer = setTimeout( refresh , 150 );
    });
    var refresh = function () { 
        // do stuff
        console.log('Stopped Scrolling'); 
    };
})();

滚动事件触发时清除计时器。滚动停止后,将触发刷新功能。

或者作为插件:

$.fn.afterwards = function (event, callback, timeout) {
    var self = $(this), delay = timeout || 16;

    self.each(function () { 
        var $t = $(this);
        $t.on(event, function(){
            if ($t.data(event+'-timeout')) {
                clearTimeout($t.data(event+'-timeout'));
            }
            $t.data(event + '-timeout', setTimeout(function () { callback.apply($t); },delay));
        })
    });
    return this;
};

要在div(带命名空间)上的最后一个滚动事件的100ms后触发回调:

$('div.mydiv').afterwards('scroll.mynamespace', function(e) {
        // do stuff when stops scrolling
        $(this).addClass('stopped');
    }, 100
);

我用它来滚动和调整大小。

答案 2 :(得分:10)

这是另一个基于提到的相同想法的更通用的解决方案:

var delayedExec = function(after, fn) {
    var timer;
    return function() {
        timer && clearTimeout(timer);
        timer = setTimeout(fn, after);
    };
};

var scrollStopper = delayedExec(500, function() {
    console.log('stopped it');
});

document.getElementById('box').addEventListener('scroll', scrollStopper);

答案 3 :(得分:2)

为什么这么复杂?正如文档所指出的,这http://jsfiddle.net/x3s7F/9/有效!

$('.frame').scroll(function() {
 $('.back').hide().fadeIn(100);
}

http://api.jquery.com/scroll/


注意: Windows Chrome上的scroll事件与其他所有事件不同。您需要快速滚动以获得与结果相同的结果。 FF。查看https://liebdich.biz/back.min.js“X”函数。

我的how many ms a scroll event测试中的一些调查结果:

  • Safari,Mac FF,Mac Chrome:约16毫秒的活动。
  • Windows FF:〜19ms一个事件。
  • Windows Chrome:当滚动缓慢时,事件最多约130毫秒。
  • Internet Explorer:最多约110毫秒的活动。

http://jsfiddle.net/TRNCFRMCN/1Lygop32/4/

答案 4 :(得分:1)

有一些scrollstart和scrollstop函数是jquery mobile的一部分。

使用scrollstop的示例:

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

希望这有助于某人。

答案 5 :(得分:1)

我还需要实施 onScrollEnd 事件。 使用计时器的想法对我有用。

我使用 JavaScript模块模式

实现此功能
var WindowCustomEventsModule = (function(){

    var _scrollEndTimeout = 30;

    var _delayedExec = function(callback){
        var timer;
        return function(){
            timer && clearTimeout(timer);
            timer = setTimeout(callback, _scrollEndTimeout);
        }
    };

    var onScrollEnd = function(callback) { 
        window.addEventListener('scroll', _delayedExec(callback), false);         
    };

    return {
        onScrollEnd: onScrollEnd
    }
})();

// usage example
WindowCustomEventsModule.onScrollEnd(function(){
    //
    // do stuff
    //
});

希望这会有助于/激励某人

答案 6 :(得分:0)

没有'scrollEnd'这样的事件。我建议您使用scroll()每隔一段时间(比如200毫秒)检查setInterval返回的值,并记录当前值和上一个值之间的差值。如果delta变为零,您可以将其用作事件。

答案 7 :(得分:0)

我从一个快速的部分中提取了一些代码,我将它拼凑在一起作为一个例子(请注意,scroll.chain是一个包含两个数组start和end的对象,它们是回调函数的容器)。另请注意,我在这里使用jQuery和下划线。

$('body').on('scroll', scrollCall);
scrollBind('end', callbackFunction);
scrollBind('start', callbackFunction);

var scrollCall = function(e) {
    if (scroll.last === false || (Date.now() - scroll.last) <= 500) {
        scroll.last = Date.now();
        if (scroll.timeout !== false) {
            window.clearTimeout(scroll.timeout);
        } else {
            _(scroll.chain.start).each(function(f){
                f.call(window, {type: 'start'}, e.event);
            });
        }
        scroll.timeout = window.setTimeout(self.scrollCall, 550, {callback: true, event: e});
        return;
    }
    if (e.callback !== undefined) {
        _(scroll.chain.end).each(function(f){
            f.call(window, {type: 'end'}, e.event);
        });
        scroll.last = false;
        scroll.timeout = false;
    }
};

var scrollBind = function(type, func) {
    type = type.toLowerCase();
    if (_(scroll.chain).has(type)) {
        if (_(scroll.chain[type]).indexOf(func) === -1) {
            scroll.chain[type].push(func);
            return true;
        }
        return false;
    }
    return false;
}