thanks_in_advance
thanks_in_advance

Reputation: 2743

AJAX firing twice (infinite scroll). Why?

I'm trying to debug an infinite scroll implementation with AJAX.


//the-JavaScript
$("#loadingDiv").hide();
var loadIndex = 0;

    $(window).scroll(function(){
        if($(window).scrollTop() == $(document).height() - $(window).height()){  


            loadIndex = loadIndex + 1;

            $("#loadingDiv").show();
            $.post("ajaxinfinitescroll.php",{loadIndex:loadIndex},function(data){

            setTimeout(function(){

                $("div.loadMoreData").append(data);

                $("#loadingDiv").hide();



            }, 1000); // wait 1 second

            })
        }
    })

//the-PHP
$loadIndex = $_POST['loadIndex'];

echo $loadIndex;

    //the-HTML
    <div class='loadMoreData'></div>
    <div id='loadingDiv'>loadingimage.gif</div>

After the first time I scroll to the end of the page, I should get a 1 in the HTML output, but I'm getting 12. The next time I scroll to the end of the page, I should end up with 12 but I actually end up with 1234.

So, the AJAX seems to be firing twice each time. Why?

Upvotes: 0

Views: 700

Answers (3)

thanks_in_advance
thanks_in_advance

Reputation: 2743

For future reference, I initially tried the following solution, but it didn't work. I implemented the isLoading concept via @Louy, but I placed it in the wrong line:

//the JavaScript
$("#loadingDiv").hide();
var loadIndex = 0;
var isLoading = false;

if (!isLoading) {
    $(window).scroll(function(){
            if($(window).scrollTop() == $(document).height() - $(window).height()){

                isLoading = true;
                loadIndex = loadIndex + 1;

                $("#loadingDiv").show();
                $.post("ajaxinfinitescroll.php", {loadIndex:loadIndex},function(data){

                setTimeout(function(){

                    $("div.loadMoreData").append(data);

                    $("#loadingDiv").hide();

                    isLoading = false;

                }, 1000); // wait 1 second

                })
        }
    })
}

Then I got help from @Praveen_Kumar, and changed the line where isLoading appears, and it worked:

//the JavaScript
$("#loadingDiv").hide();
var loadIndex = 0;
var isLoading = false;

$(window).scroll(function(){
   if (!isLoading) {
            if($(window).scrollTop() == $(document).height() - $(window).height()){

                isLoading = true;
                loadIndex = loadIndex + 1;

                $("#loadingDiv").show();
                $.post("ajaxinfinitescroll.php", {loadIndex:loadIndex},function(data){

                setTimeout(function(){

                    $("div.loadMoreData").append(data);

                    $("#loadingDiv").hide();

                    isLoading = false;

                }, 1000); // wait 1 second

                })
             }
   }
})

Upvotes: 0

Praveen Kumar Purushothaman
Praveen Kumar Purushothaman

Reputation: 167172

I guess it should work well, if you change your logic:

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

After that you must need to add a flag to check if the new content has been loaded or not and then reinitialize the scrolling function to resume back the old one.

// Add a flag
var scrolled = false;
// Change the logic
$(window).scrollTop() > $(document).height() - $(window).height()
// allow AJAX call only if not scrolled
if (!scrolled) {
  // immediately, revert the flag:
  scrolled = true;
  $.ajax(function () {
    // inside the AJAX call, restore it
    scrolled = false;
  });
}

Upvotes: 4

Louay Alakkad
Louay Alakkad

Reputation: 7408

You need to keep track of the "isLoading" state and stop the autoload behaviour while it's the case.

Even better, remove the scroll even listener while the ajax request is being loaded. Add it back once you get a response.

Upvotes: 1

Related Questions