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

You could always try using 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);
}​

EDIT:

You CAN NOT do :

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

It has to be :

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

or simply:

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

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

to call a seperate function !

The last option with a seperate function makes it easier to just unbind that function with off(), or you can unbind any function by doing :

$(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 に答える