jQuery - bind event on Scroll Stop

前端 未结 4 2063
生来不讨喜
生来不讨喜 2020-12-01 03:07

If i want to bind an event on page scrolling i can use scroll();.

But how to fire when scroll() is ended up?

I would like to reprod

相关标签:
4条回答
  • 2020-12-01 03:41

    tiny jquery way

    $.fn.scrollStopped = function(callback) {
      var that = this, $this = $(that);
      $this.scroll(function(ev) {
        clearTimeout($this.data('scrollTimeout'));
        $this.data('scrollTimeout', setTimeout(callback.bind(that), 250, ev));
      });
    };
    

    After 250 ms from the last scroll event, this will invoke the "scrollStopped" callback.

    http://jsfiddle.net/wtRrV/256/

    lodash (even smaller)

    function onScrollStopped(domElement, callback) {
      domElement.addEventListener('scroll', _.debounce(callback, 250));
    }
    

    http://jsfiddle.net/hotw1o2j/

    pure js (technically the smallest)

    function onScrollStopped(domElement, callback, timeout = 250) {
      domElement.addEventListener('scroll', () => {
        clearTimeout(callback.timeout);
        callback.timeout = setTimeout(callback, timeout);
      });
    }
    

    https://jsfiddle.net/kpsxdcv8/15/

    strange fact

    clearTimeout and clearInterval params don't have to be defined and can even be wrong types or even omitted.

    http://jsfiddle.net/2w5zLwvx/

    0 讨论(0)
  • 2020-12-01 03:48

    the event itself doesn't exist as scroll is a single event fired everytime the user scrolls by a certain increment.

    What you can do however is emulate the event.

    Credit to James Padolsey for this, lifted from his webpage:. Read it here to fully understand the code and how it is implemented.

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

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

    Probably worth noting that there are several questions related to yours, so this may be a possible duplication. e.g. Javascript: do an action after user is done scrolling and Fire event after scrollling scrollbars or mousewheel with javascript

    0 讨论(0)
  • 2020-12-01 03:53

    You can verify if window.scrollY == 0

    $(window).scroll(function(){
      if (window.scrollY == 0) {
        //...
      }
    });
    

    But this event will be fired at every scroll.

    0 讨论(0)
  • 2020-12-01 03:56

    I prefer to be able to listen on a event. This is what I do:

    The jquery plugin:

    +function(jQuery){
            var scrollStopEventEmitter = function(element, jQuery) {
                this.scrollTimeOut = false;
                this.element       = element;
                jQuery(element).on('scroll', $.proxy(this.onScroll, this));
            }
    
            scrollStopEventEmitter.prototype.onScroll = function() 
            {
                if (this.scrollTimeOut != false) {
                  clearTimeout(this.scrollTimeOut);
                }
    
                var context = this;
    
                this.scrollTimeOut = setTimeout(function(){ context.onScrollStop()}, 250);
            }
    
            scrollStopEventEmitter.prototype.onScrollStop = function() 
            {
                this.element.trigger('scrollStop');
            }
    
            jQuery.fn.scrollStopEventEmitter = function(jQuery) {   
                return new scrollStopEventEmitter(this, jQuery);
            };
    
        }($);
    

    In this case, window will now trigger scrollStop event

    $(window).scrollStopEventEmitter($);
    

    Now I can listen on scrollStop

    $(window).on('scrollStop',function(){
            // code
    
    0 讨论(0)
提交回复
热议问题