Javascript 用户停止滚动时的事件

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/3701311/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-23 05:45:55  来源:igfitidea点击:

Event when user stops scrolling

javascriptjqueryscrolljquery-events

提问by dantz

I'd like to do some fancy jQuery stuff when the user scrolls the page. But I have no idea how to tackle this problem, since there is only the scroll()method.

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

Any ideas?

有任何想法吗?

回答by Stephan Muller

You can make the scroll()have a time-out that gets overwritten each times the user scrolls. That way, when he stops after a certain amount of milliseconds your script is run, but if he scrolls in the meantime the counter will start over again and the script will wait until he is done scrolling again.

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

Update:

更新:

Because this question got some action again I figured I might as well update it with a jQuery extension that adds a scrollEndevent

因为这个问题再次得到了一些行动,我想我不妨用一个添加scrollEnd事件的 jQuery 扩展来更新它

// 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>

回答by Phil M

Here is a simple example using setTimeout to fire a function when the user stops scrolling:

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

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

The timer is cleared while the scroll event is firing. Once scrolling stops, the refresh function is fired.

触发滚动事件时清除计时器。一旦滚动停止,刷新功能就会被触发。

Or as a plugin:

或者作为插件:

$.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;
};

To fire callback after 100ms of the last scroll event on a div (with namespace):

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

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

I use this for scroll and resize.

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

回答by xat

Here is another more generic solution based on the same ideas mentioned:

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

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

回答by loveNoHate

Why so complicated? As the documentation points out, this http://jsfiddle.net/x3s7F/9/works!

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

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

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

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



Note:The scrollevent on Windows Chrome is differently to all others. You need to scroll fast to get the same as result as in e.g. FF. Look at https://liebdich.biz/back.min.jsthe "X" function.

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

Some findings from my how many ms a scroll eventtest:

我的how many ms a scroll event测试的一些发现:

  • Safari, Mac FF, Mac Chrome: ~16ms an event.
  • Windows FF: ~19ms an event.
  • Windows Chrome: up to ~130ms an event, when scrolling slow.
  • Internet Explorer: up to ~110ms an event.
  • Safari、Mac FF、Mac Chrome:约 16 毫秒一个事件。
  • Windows FF:约 19 毫秒一个事件。
  • Windows Chrome:当滚动缓慢时,事件最多约 130 毫秒。
  • Internet Explorer:一个事件最多约 110 毫秒。

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

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

回答by Dima

There are scrollstart and scrollstop functions that are part of jquery mobile.

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

Example using scrollstop:

使用滚动停止的示例:

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

Hope this helps someone.

希望这可以帮助某人。

回答by Martin Kuzdowicz

I had the need to implement onScrollEndevent discussed hear as well. The idea of using timer works for me.

我也需要实现讨论过的onScrollEnd事件。使用计时器的想法对我有用。

I implement this using JavaScript Module Pattern:

我使用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
    //
});

Hope this will help / inspire someone

希望这会帮助/激励某人

回答by dpq

There is no such event as 'scrollEnd'. I recommend that you check the value returned by scroll()every once in a while (say, 200ms) using setInterval, and record the delta between the current and the previous value. If the delta becomes zero, you can use it as your event.

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

回答by whoughton

I pulled some code out of a quick piece I cobbled together that does this as an example (note that scroll.chain is an object containing two arrays start and end that are containers for the callback functions). Also note that I am using jQuery and underscore here.

我从我拼凑的一个快速片段中提取了一些代码,作为示例(请注意,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;
}