Javascript无限滚动限制/去抖动

我在我的几个页面上设置了这个无限滚动function。 它运行得很好,但是加载更多项的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 

编辑:

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

Underscore库有以下方法:

  • _.throttle()
  • _.debounce()

你可能想要_.debounce 。 如果您不想将Underscore添加为附加依赖项,则可以从源中为所需方法创建独立方法。

看看下划线。 它们有一个很棒的去抖动包装器,可以承担任何function并返回去抖动版本。

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

如果您对实际实现感到好奇,那么源代码就很简洁了。

对我来说很好的是以下代码:

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