Reputation: 2743
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
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
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
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