代码之家  ›  专栏  ›  技术社区  ›  Bruce Adams

无限滚动和排序问题

  •  1
  • Bruce Adams  · 技术社区  · 6 年前

    我正在使用以下javascript进行无限滚动和排序:

    $(window).scroll(function () {
      if ($(window).scrollTop() + $(window).height() == $(document).height()) {
        if (!busy) {
          busy = true;
          $('#spinner').show();
          // AJAX call and append list
          $('#spinner').hide();
          busy = false;
        }
      }
    }); 
    $('#sort').on('change', function () {
      // AJAX call and replace list
    });
    

    但我遇到的问题是,在对scroll函数进行排序时也会触发,这会导致两个ajax调用,并向列表中添加比预期更多的结果。

    如何防止在对列表进行排序时触发滚动功能?

    更新

    一个简单的例子。首先向下滚动,然后进行排序,这将导致两个警报。

    JSFiddle example

    1 回复  |  直到 6 年前
        1
  •  1
  •   Bruce Adams    6 年前

    首先,不要创建所有这些随机jquery对象。创建一次,然后重用。最好的方法是把它放在一个范围内,这样其他代码就不会受到局部变量的干扰。

    +function($window, $document, $) {
       ... code here
    }(jQuery(window), jQuery(document), jQuery)
    

    那就谈谈你的问题。你需要为更新阻止你的触发状态,直到另一个完成。你有busy变量,我把它重命名为loading。

    问题是加载在排序结束时设置为true。之后,Scroll事件由JavaScript线程通过调整内容大小来触发。此事件标识要完成的加载,从而下次重新触发加载。

    您需要的是第二个变量,该变量定义滚动可能是由排序更新触发的。 我用过 triggeredByResort 为了这个。这是一个在150毫秒后自动重置为false的变量,但如果在该时间段内发生“scroll”事件,则scroll的首次出现将终止。会发生第二次。如果没有发生任何事情,变量将在150毫秒后自动重置为false。

    +function(window, document, $) {
       var $spinner = $('#spinner');
       var $sort = $('#sort');
       var $window = $(window);
       var $document = $(document);
       var triggeredByResort = false;
       var loading = false;
       var doneLoading = function() {
           $spinner.hide();
           loading = false;
       }
       var startLoading = function() {
          loading = true;
          $spinner.show();
       }
       $sort.on('change', function() { 
            var direction = $sort.val();
            startLoading();
                    $.ajax({
                       type: "POST",
                       url: 'sortstufftarget.html',
                       data: {
                          direction: direction,
                          // stuff data
                       },
                       success: function(data) {
                          triggeredByResort = true;
                          window.setTimeout(function() {
                              triggeredByResort = false;
                          }, 150);
                          // replace stuff code here
    
                          doneLoading();
                       },
                       error: function(data) {
                          window.alert('an error occured');
                          doneLoading();
                       }
                   });
       });
    
       $window.scroll(function () {
           if (!loading && $window.scrollTop() + $window.height() == $document.height()) {
                    if(triggeredByResort) {
                       triggeredByResort = false;
                       return;
                    }
                    startLoading();
                    $.ajax({
                       type: "POST",
                       url: 'loadnewstufftarget.html',
                       data: {
                          // load new stuff data
                       },
                       success: function(data) {
                          // append stuff code here
                          doneLoading();
                       },
                       error: function(data) {
                          window.alert('an error occured');
                          doneLoading();
                       }
                   });
                }
            }); 
    }(window, document, jQuery)