jQuery Infinite Scroll
Infinite scroll loads new content automatically as the user scrolls toward the bottom of the page. Instead of clicking a "Next Page" button, the page extends itself. This pattern is used by social media feeds, news sites, and product listings.
How Infinite Scroll Works
Diagram: Scroll Position vs Page Height ┌────────────────────────────┐ ← top of page (scrollTop = 0) │ Content │ │ Content │ │ Content │ │ Content │ │─────────── visible area ───│ ← scrollTop = current scroll position │ Content │ │ Content │ window.innerHeight = visible height │─────────────────────────── │ ← bottom of visible window │ Content │ └────────────────────────────┘ ← document.height (total page height) When: scrollTop + windowHeight >= documentHeight - threshold → Load more content!
Core Scroll Detection Logic
$(document).ready(function() {
var loading = false;
var page = 1;
$(window).scroll(function() {
var scrollTop = $(window).scrollTop();
var windowHeight = $(window).height();
var docHeight = $(document).height();
var threshold = 200; // load when 200px from the bottom
if (!loading && (scrollTop + windowHeight) >= (docHeight - threshold)) {
loading = true;
page++;
loadMoreContent(page);
}
});
function loadMoreContent(pageNum) {
$("#loader").show();
$.get("posts.php", { page: pageNum }, function(data) {
if (data.trim() === "") {
// No more content
$("#loader").hide();
$(window).off("scroll"); // stop listening
$("#endMessage").show();
} else {
$("#content").append(data);
$("#loader").hide();
loading = false; // allow next load
}
});
}
});
Diagram: Loading Sequence
User scrolls down
│
scroll event fires
│
Is scrollTop + windowHeight >= docHeight - 200?
│
YES and NOT already loading?
│
loading = true → prevents duplicate requests
│
$.get("posts.php?page=2")
│
Server returns new HTML posts
│
Append to #content → page grows
loading = false → ready for next trigger
│
User scrolls more → repeats
HTML Structure
<div id="content">
<!-- Initial posts loaded from server -->
<div class="post">Post 1</div>
<div class="post">Post 2</div>
<div class="post">Post 3</div>
</div>
<div id="loader" style="display:none;">Loading more...</div>
<div id="endMessage" style="display:none;">No more posts.</div>
Server-Side posts.php (PHP Example)
<?php
$page = intval($_GET['page'] ?? 1);
$perPage = 5;
$offset = ($page - 1) * $perPage;
// Fetch posts from database
$posts = getPostsFromDB($offset, $perPage);
if (empty($posts)) {
echo ""; // empty response signals no more content
} else {
foreach ($posts as $post) {
echo "<div class='post'><h3>" . $post['title'] . "</h3><p>" . $post['excerpt'] . "</p></div>";
}
}
?>
Throttling Scroll Events
The scroll event fires many times per second. Throttling it reduces unnecessary computation and improves performance.
var scrollTimer;
$(window).scroll(function() {
clearTimeout(scrollTimer);
scrollTimer = setTimeout(function() {
// Scroll check logic runs only after scrolling pauses for 100ms
var scrollTop = $(window).scrollTop();
var windowHeight = $(window).height();
var docHeight = $(document).height();
if (!loading && (scrollTop + windowHeight) >= (docHeight - 200)) {
loading = true;
page++;
loadMoreContent(page);
}
}, 100);
});
Load More Button Alternative
Some users prefer a "Load More" button over automatic loading — especially on mobile where auto-loading can cause accidental footer skips. You can combine both: show a button when near the bottom, then auto-load if they keep scrolling.
$(document).ready(function() {
$("#loadMoreBtn").click(function() {
page++;
$(this).text("Loading...").prop("disabled", true);
$.get("posts.php", { page: page }, function(data) {
if (data.trim() === "") {
$("#loadMoreBtn").hide();
$("#endMessage").show();
} else {
$("#content").append(data);
$("#loadMoreBtn").text("Load More").prop("disabled", false);
}
});
});
});
Infinite Scroll Best Practices
- Always show a loading indicator so users know more content is coming.
- Use the
loadingflag to prevent duplicate AJAX requests. - Stop the scroll listener (
$(window).off("scroll")) when no more content exists. - Throttle scroll events to avoid performance issues.
- Show a clear end-of-feed message when all content has loaded.
- Consider offering a "Load More" button as a fallback for users who prefer it.
Quick Summary
- Detect scroll position with
$(window).scrollTop() + $(window).height() >= $(document).height() - threshold. - Use a boolean
loadingflag to prevent multiple simultaneous AJAX requests. - Append fetched HTML to the content container and reset the flag when done.
- Stop listening for scroll events when the server returns empty content.
- Throttle the scroll handler to improve performance on fast scrolling.
