1

所以我一直在阅读这个问题,并看到了很多不同的解决方案。目前我的代码如下所示:

我正在使用这个插件:http ://benalman.com/projects/jquery-throttle-debounce-plugin/

// Bind throttled scroll event to load new items when page is scrolled to the bottom.
$(window).data('loading', false).scroll($.throttle(800, Olemas.ScrollLoad));

Olemas.ScrollLoad = function()  {
  if ($(window).data('loading') == true) return;
  if ($(window).scrollTop() >= ($(document).height() - $(window).height())) {
      if (Olemas.NextPage <= Olemas.MaxPage) {
          $(window).unbind('scroll'); // I have tried unbinding the event to stop it from launching
          Olemas.LoadMoreItems(Olemas.DivToUpdate); // load the new items
          $(window).data('loading', false).scroll($.throttle(800, Olemas.ScrollLoad)); // rebind scroll event.
      }

  }
};

问题是即使事件每 800 毫秒触发一次。当我快速滚动到底部时,滚动事件触发太多次并且页面加载都错误。

if ($(window).scrollTop() >= ($(document).height() - $(window).height()))

在我的项目加载到页面后,此语句不应该通过,但它仍然通过几次之后才意识到页面高度已更改。高度属性是否可能更新得不够快,或者滚动事件已经以某种方式加载到 DOM 中?

在 LoadMoreItems 函数扩展页面后,我能做些什么来阻止滚动事件触发。

编辑。

所以在这个函数中,警报运行 2 次,然后在 LoadMoreItems ajax 成功中发出警报。

Olemas.ScrollLoad = function()  {
/// <summary>
/// Loads more items when scrolled to the bottom.
/// </summary>
if ($(window).data('loading') == true) return;
if ($(window).scrollTop() >= ($(document).height() - $(window).height())) {
    if (Olemas.NextPage <= Olemas.MaxPage) {
        alert(Olemas.NextPage); // This runs 2 times, before the LoadMoreItems changes the NextPage value
        $(window).off('scroll', $.throttle(800, Olemas.ScrollLoad));

        Olemas.LoadMoreItems(Olemas.DivToUpdate);
        $(window).data('loading', false).on('scroll', $.throttle(800, Olemas.ScrollLoad)); // rebind scroll event.
    }

}
};

Olemas.LoadMoreItems = function () {
  $(window).data('loading', true);
  $.ajax({
      url: Olemas.ActionLink,
      data: { "page": Olemas.NextPage, "facId": Olemas.FacultyId },
      success: function (data) {
          $(".loadingImage").hide();
          $(data).appendTo(Olemas.DivToUpdate);
          alert("Done") // This is run after the previous alerts have fired 2 times.
          Olemas.NextPage++;
          Olemas.CheckPages();
      }
  });
  return false;

};
4

3 回答 3

2

好的,所以我的问题如下:

// Bind throttled scroll event to load new items when page is scrolled to the bottom.
$(window).data('loading', false).scroll($.throttle(800, Olemas.ScrollLoad));

Olemas.ScrollLoad = function()  {
  if ($(window).data('loading') == true) return;
  if ($(window).scrollTop() >= ($(document).height() - $(window).height())) {
   if (Olemas.NextPage <= Olemas.MaxPage) {
      $(window).unbind('scroll'); // I have tried unbinding the event to stop it from launching
      Olemas.LoadMoreItems(Olemas.DivToUpdate); // load the new items
      $(window).data('loading', false).scroll($.throttle(800, Olemas.ScrollLoad)); // rebind scroll event.
      //The LoadMoreItems was an AJAX method and the rebinding was made before the ajax call had succeeded. 
      //That is why it fired the scroll event too many times.
  }

}
};

我通过将加载布尔检查移动到 LoadMoreItems 方法来解决它,这样该方法必须在重新绑定滚动之前完成。

于 2012-08-12T17:16:04.870 回答
0

您可以随时尝试使用on()/ off()

$(window).data('loading', false).on('scroll', doScroll);

Olemas.ScrollLoad = function() {
    if ($(window).data('loading') == true) return;
    if ($(window).scrollTop() >= ($(document).height() - $(window).height())) {
        if (Olemas.NextPage <= Olemas.MaxPage) {
            $(window).off('scroll', doScroll);
            Olemas.LoadMoreItems(Olemas.DivToUpdate); // load the new items
            $(window).data('loading', false).on('scroll', doScroll);
        }
    }
};

function doScroll() {
    $.throttle(800, Olemas.ScrollLoad);
}​

编辑:

你不能这样做:

$(window).on('scroll', $.throttle(800, Olemas.ScrollLoad));

它一定要是 :

$(window).on('scroll', function() {
    $.throttle(800, Olemas.ScrollLoad));
});

或者简单地说:

$(window).on('scroll', doScroll);

function doScroll() {
    $.throttle(800, Olemas.ScrollLoad);
}​

调用一个单独的函数!

带有单独函数的最后一个选项可以更轻松地取消绑定该函数off(),或者您可以通过执行以下操作取消绑定任何函数:

$(window).off('scroll');
于 2012-08-12T14:30:30.533 回答
0

这是我的时间戳和间隔的解决方案。滚动功能完成后最后一次触发事件需要间隔。出于性能原因,我将延迟设置为 50。这个例子每 2 秒触发一次函数,自定义有趣。

    var interval, timestamp = Date.now(),

    scrollFunction = function() {
        console.log('fire');
    },

    scrollHandler = function() {
        if(!interval) {
            interval = setInterval(() => {
                if((Date.now() - timestamp) > 2000) {
                    timestamp = Date.now();
                    scrollFunction();
                    clearInterval(interval);
                    interval = undefined;
                }
            }, 50);
        }
    }

window.addEventListener('scroll', scrollHandler);
scrollHandler();
于 2020-08-06T08:23:06.080 回答