Infinite scroll is a popular design pattern that allows users to continuously load more content as they reach the end of a page, rather than having to click to go to another page. This smooth and seamless experience can be particularly useful for blogs, social media feeds, or image galleries. In this article, we’ll walk through building a basic infinite scroll with JavaScript and an API.
Infinite scroll enhances user engagement by loading content in a continuous stream. When implemented properly, infinite scroll can improve both the user experience and retention by keeping visitors engaged with fresh content.
We’ll use JavaScript to monitor when the user scrolls to the bottom of the page and then trigger a function that fetches additional content from an API. Here’s what you’ll need:
Let’s start by creating a simple HTML structure for displaying content and a loading indicator:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Infinite Scroll Demo</title>
<link rel="stylesheet" href="styles.css">
</head>
<body>
<div id="content-container"></div>
<div id="loading">Loading...</div>
<script src="script.js"></script>
</body>
</html>
Here’s some basic styling for the container and loading indicator:
/* styles.css */
body {
font-family: Arial, sans-serif;
margin: 0;
padding: 0;
}
#content-container {
max-width: 600px;
margin: 20px auto;
padding: 10px;
}
#loading {
text-align: center;
padding: 20px;
font-size: 1.2em;
display: none; /* Initially hidden */}
The #loading
div will display when we’re fetching new data.
Let’s set up JavaScript to fetch data from a placeholder API like JSONPlaceholder. We’ll create a function called fetchData()
that retrieves data and appends it to the content container.
// script.js
let page = 1; // Start on page 1
async function fetchData() {
document.getElementById('loading').style.display = 'block';
try {
const response = await fetch(`https://jsonplaceholder.typicode.com/posts?_page=${page}&_limit=5`);
const data = await response.json();
data.forEach(item => {
const post = document.createElement('div');
post.classList.add('post');
post.innerHTML = `
<h2>${item.title}</h2>
<p>${item.body}</p>
`;
document.getElementById('content-container').appendChild(post);
});
page++; // Increase page count after loading data
} catch (error) {
console.error('Error fetching data:', error);
}
document.getElementById('loading').style.display = 'none';
}
Now, we’ll add an event listener to detect when the user scrolls near the bottom of the page. When that happens, fetchData()
will be called to load additional data.
// Infinite scroll event listener
window.addEventListener('scroll', () => {
const { scrollTop, scrollHeight, clientHeight } = document.documentElement;
if (scrollTop + clientHeight >= scrollHeight - 5) {
fetchData();
}
});
// Initial fetch for first set of data
fetchData();
When scrollTop + clientHeight
is close to scrollHeight
, it’s time to load more data. We then call fetchData()
again, which loads new posts.
To improve the user experience, we’ve included a loading indicator. This will show up while new data is being fetched:
#loading
to display: block
when data fetch begins.#loading
again.HTML:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Infinite Scroll Demo</title>
<link rel="stylesheet" href="styles.css">
</head>
<body>
<div id="content-container"></div>
<div id="loading">Loading...</div>
<script src="script.js"></script>
</body>
</html>
CSS:
/* styles.css */
body {
font-family: Arial, sans-serif;
margin: 0;
padding: 0;
}
#content-container {
max-width: 600px;
margin: 20px auto;
padding: 10px;
}
#loading {
text-align: center;
padding: 20px;
font-size: 1.2em;
display: none; /* Initially hidden */}
.post {
margin-bottom: 20px;
padding: 15px;
border: 1px solid #ddd;
border-radius: 8px;
box-shadow: 0px 0px 5px rgba(0, 0, 0, 0.1);
}
.post h2 {
margin: 0 0 10px;
}
.post p {
margin: 0;
}
JavaScript:
// script.js
let page = 1; // Start on page 1
async function fetchData() {
document.getElementById('loading').style.display = 'block';
try {
const response = await fetch(`https://jsonplaceholder.typicode.com/posts?_page=${page}&_limit=5`);
const data = await response.json();
data.forEach(item => {
const post = document.createElement('div');
post.classList.add('post');
post.innerHTML = `
<h2>${item.title}</h2>
<p>${item.body}</p>
`;
document.getElementById('content-container').appendChild(post);
});
page++; // Increase page count after loading data
} catch (error) {
console.error('Error fetching data:', error);
}
document.getElementById('loading').style.display = 'none';
}
// Infinite scroll event listener
window.addEventListener('scroll', () => {
const { scrollTop, scrollHeight, clientHeight } = document.documentElement;
if (scrollTop + clientHeight >= scrollHeight - 5) {
fetchData();
}
});
// Initial fetch for first set of data
fetchData();
You’ve just implemented an infinite scroll feature using JavaScript and an API. By using this approach, you can build a seamless, engaging user experience that loads more content only when needed. Try experimenting with the number of posts loaded, the API endpoint, or even styling to make it more unique.
Top 5 JavaScript console Methods to simplify debugging
Hackers are exploiting Microsoft Teams to deceive users into installing remote access tools, granting attackers…
Data plays an essential role in our lives. We each consume and produce huge amounts…
Thomas E. Kurtz, co-creator of the BASIC programming language, passed away on November 12, 2024,…
Mark Cuban recently expressed his views on the impact of artificial intelligence (AI) on the…
Harvard researchers have developed a new AI training dataset, the Harvard OpenAI-Microsoft Dataset, aimed at…
Apple's iOS 18.2 Update Introduces Powerful AI Features, Including Genmoji and Image Playground Apple’s latest…