Looking at this code, I especially did not like how it was configured. The script requires some caching of elements, so you do not constantly call the same selector, for example, again and again.
I used the inproc (in process) variable in the callback of the anonymous onDOMReady function. This is set at the top level, but due to the closure provided by the anonymous function, this variable will remain available for the contained functions. Here I check if this is true or not.
You will see that I moved all your jQuery calls to the beginning and added them as variables. This is called caching and helps prevent the same requests from repeating over and over in the same script. It is much more efficient. Note that $('div#id') will work, but you do not need the prefix a id ; just start with id , for example $('#id') . All that is really not needed before is IMO.
I also set the preload distance to 200px . 50px not as high as you probably think; it's barely noticeable that different.
The whole timeout is designed to delay the loading of content so that you can test the scroll. Open Firebug to see the console.log() message.
This script is highly dependent on testing variables and functions, but you should be able to remove everything that says βFor testing purposesβ or some variations of this, and make it work fine.
// For test purposes. var i = 0; $(document).ready(function(){ var inproc = false, id, $win = $(window), $doc = $(document), $bloglist = $("#bloglist"), $loadmore = $('#loadmoreajaxloader'), // For test purposes. dummycontent = $('.dummycontent').html(), loadtimeout = false; // Note, load is for testing; it goes with the setTimeout(). var callbackBlogLoaded = function(html){ var self = this; // For testing purposes. if (loadtimeout !== false) { loadtimeout = false; setTimeout(function(html){ callbackBlogLoaded.call(self, html); }, 3000); return false; } inproc = false; // For test purposes. i++; html = dummycontent; if (i > 5) html = ''; if (html) { // For test purposes. $bloglist.append('<p style="color: red; font-weight: bold;">i is ' + i + ' of 5 total</p>' + html); $loadmore.hide(); } else { // <center> is deprecated; use a class on a P or DIV instead. $loadmore.html('<p class="center">No more posts to show.</p>'); } }; // For test purposes. $bloglist.append($('.dummycontent').html()); $win.scroll(function(){ // You need to subtract the scroll-load pad distance from the // right-side height calculation, not .scrollTop(). if ($win.scrollTop() > ($doc.height() - $win.height() - 200)){ if (inproc == true) { // For testing purposes. console.log('Content load blocked: In process with another request.'); return false; } inproc = true; id = $bloglist.has(':last').attr('id'); // For test purposes id = 10; loadtimeout = true; $loadmore.show(); // The /echo/html/ is for testing purposes. $.post("/echo/html/", { pid: id }, callbackBlogLoaded); }; }); });
http://jsfiddle.net/xUsEA/2/