无法停止滚动事件多次发射

时间:2012-08-12 14:22:04

标签: jquery jquery-plugins jquery-pagination

所以我一直在阅读这个问题并且已经看到了很多不同的解决方案。目前我的代码看起来像这样:

我正在使用此插件: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函数扩展页面后,我该怎么做才能阻止滚动事件的触发。

EDIT。

因此,在此函数中,警报运行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;

};

3 个答案:

答案 0 :(得分: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方法来解决它,这样方法必须在滚动重新绑定之前完成。

答案 1 :(得分: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');

答案 2 :(得分: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();