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呼び出しがまったく実行されていないようです。すぐにtrueに設定していなくても、スクロールを停止するとすぐに実行されるはずですが、まったく実行されません。

4

3 に答える 3

2

アンダースコアライブラリには、このためのメソッドがあります。

あなたはおそらく欲しいです_.debounce。追加の依存関係としてアンダースコアを追加したくない場合は、必要なメソッドのソースからスタンドアロンメソッドを作成できる場合があります。

于 2012-07-13T19:38:12.613 に答える
0

アンダースコアを見てください。それらには、任意の関数を取り、デバウンスされたバージョンを返すことができる、すばらしい小さなデバウンスラッパーがあります。

そのスクロールコールバック関数を取得して、それを。に置き換えることができるはずです_.debounce(function(){ ... your code ... }, 100)

実際の実装に興味がある場合は、ソースコードが素晴らしく簡潔です。

于 2012-07-13T19:39:50.673 に答える
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 に答える