无限滚动和排序问题

时间:2018-07-05 13:48:18

标签: javascript jquery infinite-scroll

我正在使用以下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
});

但是我遇到的问题是,在对滚动功能进行排序时,还引发了2个AJAX调用,并向列表中添加了比预期更多的结果。

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

更新

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

JSFiddle example

1 个答案:

答案 0 :(得分:1)

首先,不要创建所有这些随机jquery对象。创建一次,然后重用。最好的方法是将其放入范围内,以使其他代码不受本地变量的干扰。

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

然后处理您的问题。您需要阻止触发状态以进行更新,直到另一个完成为止。您有忙碌的变量,我将其重命名为loading。

问题是排序结束时加载设置为true。之后,滚动事件由javascript线程通过调整内容的大小触发。此事件表明要完成的加载,因此接下来重新触发加载。

您需要的是第二个变量,该变量定义滚动可能是由排序更新触发的。 我为此使用了triggeredByResort。这个变量会在150毫秒后自动重置为false,但是如果在该时间段内发生“滚动”事件,则会终止第一次滚动。将再次发生。如果没有任何反应,则该变量将在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)