我怎么知道我什么时候停止滚动?

IT技术 javascript scroll dom-events
2021-01-27 07:02:50

我如何知道我何时停止使用 Javascript 滚动?

6个回答

您可以为事件添加事件处理程序scroll并启动超时。就像是:

var timer = null;
window.addEventListener('scroll', function() {
    if(timer !== null) {
        clearTimeout(timer);        
    }
    timer = setTimeout(function() {
          // do something
    }, 150);
}, false);

这将启动超时并等待 150 毫秒。如果scroll在此期间发生了新事件,则中止计时器并创建一个新事件。如果没有,该函数将被执行。您可能需要调整时间。

还要注意 IE 使用不同的方式来附加事件侦听器,这应该给一个很好的介绍:quirksmode - Advanced event Registration models

如果$(window)是 jQuery,addEventListener则未定义。$(window).on('scroll')可能工作。
2021-03-16 07:02:50
感谢您的评论,问题是当保持滚动时仍然setTimeout有效:(,有没有什么解决方案可以在停止工作时运行代码,例如jQuery回调?#
2021-03-24 07:02:50
我还是不明白问题所在。回调只是一个传递给另一个函数并被另一个函数调用的函数。例如,传递给的函数setTimeout是回调或事件处理程序是回调。无论如何,如果您有实际问题/疑问,请提出问题
2021-03-24 07:02:50
我建议回调
2021-03-31 07:02:50
@bboymaanu:我不知道你想用那个评论告诉我什么。请详细说明。
2021-04-13 07:02:50

没有“停止滚动”事件。如果你想在用户完成滚动后做一些事情,你可以在“OnScroll”事件中设置一个计时器。如果您触发另一个“OnScroll”事件,则重置计时器。当计时器最终触发时,您可以假设滚动已停止。我认为 500 毫秒是一个很好的开始时间。

下面是一些适用于 IE 和 Chrome 的示例代码:

<html>

<body onscroll="bodyScroll();">

  <script language="javascript">
    var scrollTimer = -1;

    function bodyScroll() {
      document.body.style.backgroundColor = "white";

      if (scrollTimer != -1)
        clearTimeout(scrollTimer);

      scrollTimer = window.setTimeout("scrollFinished()", 500);
    }

    function scrollFinished() {
      document.body.style.backgroundColor = "red";
    }
  </script>

  <div style="height:2000px;">
    Scroll the page down. The page will turn red when the scrolling has finished.
  </div>

</body>

</html>

@MerakMarey 我猜你不熟悉Needs More jQuery有时纯 JavaScript 是一种罕见的享受 :) PS 我对魔术表演不感兴趣。我想知道幕后发生了什么。
2021-03-17 07:02:50
现在很难在堆栈上找到纯 JS,感谢合法的非 jQuery 解决方案。
2021-03-20 07:02:50
@akinuri 这是一个很好的笑话,但仅此而已......一个笑话......抽象所有“魔术工作”的框架的想法比知道幕后是什么更有益......(你仍然可以这样做,如果你想......jQuery仍然是Javascript......你可以改变,甚至改进代码或你想做的任何事情........但这会让你偏离主要目标,即获得工作及时完成……这比了解所有小细节更重要……相信我,我曾经有过同样的看法……但不……现在我知道了: var a =1; var b =null; $.when(b=a+2).then(alert(b)); :)
2021-03-27 07:02:50
感谢您提供纯 javascript、非 jQuery 代码和有效示例!它也适用于 Firefox。
2021-04-04 07:02:50
(function( $ ) {
        $(function() {
            var $output = $( "#output" ),
                scrolling = "<span id='scrolling'>Scrolling</span>",
                stopped = "<span id='stopped'>Stopped</span>";
                $( window ).scroll(function() {
                    $output.html( scrolling );
                    clearTimeout( $.data( this, "scrollCheck" ) );
                    $.data( this, "scrollCheck", setTimeout(function() {
                        $output.html( stopped );
                    }, 250) );
    
                });
        });
    })( jQuery );

========>>>> 这里的工作示例

请不要对多个问题发布相同的答案。发布一个好的答案,然后投票/标记以关闭其他重复的问题。如果问题不是重复的,请定制您对问题的答案
2021-03-17 07:02:50
当所有其他方法都失败时,它起作用了。但是,您能否详细解释一下“scrollCheck”?
2021-03-24 07:02:50
@kleopatra 好建议。我将此答案发布到每个问题的原因,以便每个人都可以从中受益。有很多与此相关的问题。也许它对任何问题的人都有用。
2021-04-02 07:02:50

这是我在名为scroll-into-view-if-needed的 repo 中找到的更现代的基于 Promise 的解决方案

它不是addEventListenerscroll事件上使用requestAnimationFrame而是用于观察没有移动的帧,并在有 20 帧没有移动时进行解析。

function waitForScrollEnd () {
    let last_changed_frame = 0
    let last_x = window.scrollX
    let last_y = window.scrollY

    return new Promise( resolve => {
        function tick(frames) {
            // We requestAnimationFrame either for 500 frames or until 20 frames with
            // no change have been observed.
            if (frames >= 500 || frames - last_changed_frame > 20) {
                resolve()
            } else {
                if (window.scrollX != last_x || window.scrollY != last_y) {
                    last_changed_frame = frames
                    last_x = window.scrollX
                    last_y = window.scrollY
                }
                requestAnimationFrame(tick.bind(null, frames + 1))
            }
        }
        tick(0)
    })
}

使用 async/await 然后

await waitForScrollEnd()

waitForScrollEnd().then(() => { /* Do things */ })

我做了这样的事情:

var scrollEvents = (function(document, $){

    var d = {
        scrolling: false,
        scrollDirection : 'none',
        scrollTop: 0,
        eventRegister: {
            scroll: [],
            scrollToTop: [],
            scrollToBottom: [],
            scrollStarted: [],
            scrollStopped: [],
            scrollToTopStarted: [],
            scrollToBottomStarted: []
        },
        getScrollTop: function(){ 
            return d.scrollTop;
        },
        setScrollTop: function(y){
            d.scrollTop = y;
        },
        isScrolling: function(){
            return d.scrolling;
        },
        setScrolling: function(bool){
            var oldVal = d.isScrolling();
            d.scrolling = bool;
            if(bool){
                d.executeCallbacks('scroll');
                if(oldVal !== bool){
                    d.executeCallbacks('scrollStarted');
                }
            }else{
                d.executeCallbacks('scrollStopped');
            }
        },
        getScrollDirection : function(){
            return d.scrollDirection;
        },
        setScrollDirection : function(direction){
            var oldDirection = d.getScrollDirection();
            d.scrollDirection = direction;
            if(direction === 'UP'){
                d.executeCallbacks('scrollToTop');
                if(direction !== oldDirection){
                    d.executeCallbacks('scrollToTopStarted');
                }
            }else if(direction === 'DOWN'){
                d.executeCallbacks('scrollToBottom');
                if(direction !== oldDirection){
                    d.executeCallbacks('scrollToBottomStarted');
                }
            }
        },
        init : function(){
            d.setScrollTop($(document).scrollTop());
            var timer = null;
            $(window).scroll(function(){
                d.setScrolling(true);
                var x = d.getScrollTop();
                setTimeout(function(){
                    var y = $(document).scrollTop();
                    d.setScrollTop(y);
                    if(x > y){
                        d.setScrollDirection('UP');
                    }else{
                        d.setScrollDirection('DOWN');
                    }
                }, 100);
                if(timer !== 'undefined' && timer !== null){
                    clearTimeout(timer);
                }
                timer = setTimeout(function(){
                    d.setScrolling(false);
                    d.setScrollDirection('NONE');
                }, 200);
            });
        },
        registerEvents : function(eventName, callback){
            if(typeof eventName !== 'undefined' && typeof callback === 'function' && typeof d.eventRegister[eventName] !== 'undefined'){
                d.eventRegister[eventName].push(callback);
            }
        },
        executeCallbacks: function(eventName){
            var callabacks = d.eventRegister[eventName];
            for(var k in callabacks){
                if(callabacks.hasOwnProperty(k)){
                    callabacks[k](d.getScrollTop());
                }
            }
        }
    };
    return d;

})(document, $);

代码在此处可用:documentScrollEvents