0

我在我的几个页面上设置了这个无限滚动功能。它工作得非常好,但是加载更多项目的 Ajax 调用会进行多次数据库调用,并且每次都必须加载大量图像,并且通常需要几秒钟才能加载。根据我的连接情况,我将其计时在 3 到 7 秒之间。因此,当浏览器决定多次触发滚动事件时,它可能会变成真正的火车残骸。我怎样才能对它进行节流或去抖动,以使浏览器不会在几秒钟内多次运行 Ajax 调用并使一切停止?

$(document).ready() 
{
    //Infinite scroll
   $(window).on('scroll', _.debounce( function(){
      var height = $(window).height();
      var scrollTop = $(window).scrollTop();
      var dHeight = getDocHeight();

      if( height + scrollTop >= dHeight - 100) 
      {
        //Display items that were previously hidden 
         showAllItems();
         if(!vloaded < START_NUM && !done){
             //Load next set of items
             $.ajax
             ({
              type: "POST",
              url: "/organizer/getMore",
              data: { filter: vfilter, loaded: vloaded },
              dataType: "html",
              success: function( responseText, textStatus, XHR )
              {
                if(responseText.indexOf("// GRID ENTRY //") < 0){   //Out of items to load
                    done = true;
                }
                else{
                    //Display items that were previously hidden 
                    showAllItems();
                    // select the element with the ID grid and insert the HTML
                    $( "#grid" ).append( responseText );
                    //alert("Loaded "+vloaded+" items");
                }
              }
            });
          // global variable
          vloaded +=LOAD_NUM;
      } // if
      }
    }
  }, 500, true)); // on
} // ready

编辑:

我下载了下划线并添加了去抖动功能,但现在 Ajax 调用似乎根本没有运行。即使我没有将 immediate 设置为 true,它应该在我停止滚动后很快执行,但它根本不执行。

4

3 回答 3

2

Underscore 库有这方面的方法:

你可能想要_.debounce. 如果您不想将下划线添加为附加依赖项,您可以从源代码中为您想要的方法创建一个独立的方法。

于 2012-07-13T19:38:12.613 回答
0

对我有用的是以下代码:

setupPaginationOnScroll: function() {
    var self = this;
    var loadNextPageIfNotLoadingThrottled = _.throttle(function() {
        if ( !self.isLastPageLoading() ) {
            self.loadNextPage()
        }
    },1000);
    this.onScrollbarNearBottom(loadNextPageIfNotLoadingThrottled);
},

你会注意到我使用了油门而不是去抖动,当有一个挂起的请求时,我只是忽略了滚动事件

这部分也可能让您感兴趣:

onScrollbarNearBottom: function(callback) {
    var target = this.getDOMNode();
    $(target).scroll(function(e) {
        if ( ScrollUtils.isScrollbarNearBottom(target) ) {
            callback(e);
        }
    });
}



module.exports = {

    debug: false,

    /**
     * We consider someone is near the bottom if he has scrolled more than 90%
     */
    scrollNearThreshold: 90,


    /**
     * Useful function to detect for exemple when to load more content (ie another page)
     * if the user has almost scrolled to the bottom
     *
     * @return {boolean}
     */
    isWindowScrollbarNearBottom: function() {
        return this.isScrollbarNearBottom(window);
    },

    isScrollbarNearBottom: function(scrollableElementSelector) {
        return this.getScrollPercentage(scrollableElementSelector) > this.scrollNearThreshold;
    },


    /**
     * Returns the percentage of scroll in a given container.
     * If the scrollbar is at the beginning it should return 0.
     * If the scrollbar is at the end it should return 100 (almost :s)
     *
     * See http://stackoverflow.com/questions/22867584/get-scroll-percentage-in-a-dom-container
     * For an unknown reason it sometimes returns a value > 100 (like 103 if you are at the bottom)
     * It is not very precise but at least it should work rather well for most usecases.
     *
     * @return {number}
     */
    getScrollPercentage: function(scrollableElementSelector) {

        var scrollableElement = $(scrollableElementSelector);

        // This is the number of hidden pixels of the scrollable element inside its container
        var hiddenHeigth;
        if ( scrollableElementSelector === window ) {
            hiddenHeigth = $(document).height() - $(window).height();
        } else {
            hiddenHeigth = scrollableElement[0].scrollHeight - scrollableElement.outerHeight();
        }

        // This is the number of scrolled pixels
        var scrolledHeight = scrollableElement.scrollTop();

        //if ( hiddenHeigth < scrolledHeight ) {
        //throw new Error("hiddenHeigth "+hiddenHeigth+" < scrolledHeight " +scrolledHeight + " -> Impossible unless you didn't use this function correctly");
        //}

        var scrollPercent = ( scrolledHeight / hiddenHeigth ) * 100;

        if ( this.debug ) {
            console.debug("hiddenHeigth=",hiddenHeigth,"scrolledHeight=",scrolledHeight,"scrollPercent=",scrollPercent);
        }

        return scrollPercent;
    }

}
于 2014-07-17T09:02:20.307 回答
0

看看下划线。他们有一个很棒的小去抖动包装器,可以接受任何函数并返回去抖动版本。

您应该能够使用该滚动回调函数并将其替换为_.debounce(function(){ ... your code ... }, 100).

如果您对实际实现感到好奇,源代码非常简洁明了。

于 2012-07-13T19:39:50.673 回答