Marc Marc - 7 months ago 47
Javascript Question

jQuery Infinite Scroll - event fires multiple times when scrolling is fast

Okay, the code below "works" in that when you scroll to the bottom of the page the AJAX function is fired and results are appended to the #postswrapper div on the page.

The issue is: if I scroll really quickly when I reach the bottom of the page, the AJAX fires several times and loads several sets of results into the #postswrapper div (number of additional, 'unwanted' results are determined by how many additional scroll events were fired by scrolling quickly).

Ultimately, I need only serve one set of results per time the user reaches the bottom. I've tried adding timers and such, but to no avail. It's obviously storing the additional scroll actions in the DOM and firing them in sequential order thereafter.

Any ideas?

I'm using jquery.1.4.4.js if that helps anybody. And e.preventDefault() doesn't work, in this situation, anyways.

$(window).scroll(function(e) {
e.preventDefault();
if ($(window).scrollTop() >= ($(document).height() - $(window).height())) {
$('div#loadmoreajaxloader').show();
$.ajax({
cache: false,
url: 'loadmore.php?lastid=' + $('.postitem:last').attr('id'),
success: function(html) {
if (html) {
$('#postswrapper').append(html);
$('div#loadmoreajaxloader').hide();
} else {
$('div#loadmoreajaxloader').html();
}
}
});
}
});

Answer

Try storing some kind of data that stores whether the page is currently loading new items. Maybe like this:

$(window).data('ajaxready', true).scroll(function(e) {
    if ($(window).data('ajaxready') == false) return;

    if ($(window).scrollTop() >= ($(document).height() - $(window).height())) {
        $('div#loadmoreajaxloader').show();
        $(window).data('ajaxready', false);
        $.ajax({
            cache: false,
            url: 'loadmore.php?lastid=' + $('.postitem:last').attr('id'),
            success: function(html) {
                if (html) {
                    $('#postswrapper').append(html);
                    $('div#loadmoreajaxloader').hide();
                } else {
                    $('div#loadmoreajaxloader').html();
                }
                $(window).data('ajaxready', true);
            }
        });
    }
});

Right before the Ajax request is sent, a flag is cleared signifying that the document is not ready for more Ajax requests. Once the Ajax completes successfully, it sets the flag back to true, and more requests can be triggered.