Infinite Scroll in JS & React
In JS:
Infinite scroll is a technique used in web development to load content dynamically as the user scrolls down a webpage, creating an endless scrolling effect without requiring the user to navigate to a new page. Below is a basic example of how to implement infinite scroll using JavaScript:
HTML Structure
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Infinite Scroll Example</title>
<style>
/* Basic styling */
body {
font-family: Arial, sans-serif;
}
#content {
max-width: 600px;
margin: 0 auto;
padding: 20px;
}
.post {
margin: 20px 0;
padding: 15px;
border: 1px solid #ddd;
background-color: #f9f9f9;
}
</style>
</head>
<body>
<div id="content">
<!-- Posts will be added here dynamically -->
</div>
<script src="infinite-scroll.js"></script>
</body>
</html>
JavaScript Implementation
// infinite-scroll.js
document.addEventListener("DOMContentLoaded", function() {
const content = document.getElementById('content');
let page = 1;
function loadPosts(page) {
// Simulate fetching data from an API
return new Promise((resolve) => {
setTimeout(() => {
let posts = '';
for (let i = 1; i <= 10; i++) {
posts += `<div class="post">Post ${((page - 1) * 10) + i}</div>`;
}
resolve(posts);
}, 1000);
});
}
async function addPosts() {
const posts = await loadPosts(page);
content.innerHTML += posts;
page++;
}
function handleScroll() {
if (window.innerHeight + window.scrollY >= document.body.offsetHeight - 100) {
addPosts();
}
}
// Initial load
addPosts();
// Attach the scroll event listener
window.addEventListener('scroll', handleScroll);
});
How It Works:
HTML Structure: The
#content
div is where posts are dynamically added.JavaScript Logic:
loadPosts(): Simulates an API call by returning a promise that resolves after a short delay with 10 new posts.
addPosts(): Calls
loadPosts()
to get new posts and appends them to the#content
div.handleScroll(): Checks if the user has scrolled near the bottom of the page. If so, it loads more posts.
Event Listener: The scroll event listener triggers the
handleScroll()
function to load new content when necessary.
This basic example simulates an API call with a delay. In a real-world scenario, you would replace loadPosts()
with an actual API call to fetch new content.
\============================================
In React:
To implement infinite scroll in React, you can follow these steps:
1. Set Up State and Effect
Start by setting up state to track the items to be displayed and an effect to handle the scroll event.
import React, { useState, useEffect } from 'react';
const InfiniteScroll = () => {
const [items, setItems] = useState(Array.from({ length: 20 }));
const [hasMore, setHasMore] = useState(true);
useEffect(() => {
window.addEventListener('scroll', handleScroll);
return () => window.removeEventListener('scroll', handleScroll);
}, []);
const handleScroll = () => {
if (
window.innerHeight + document.documentElement.scrollTop >=
document.documentElement.offsetHeight - 100
)
return;
loadMoreItems();
};
const loadMoreItems = () => {
if (!hasMore) return;
setTimeout(() => {
setItems((prevItems) => [
...prevItems,
...Array.from({ length: 20 }),
]);
}, 1500);
};
return (
<div>
{items.map((_, index) => (
<div key={index} style={{ height: 50, border: '1px solid black', margin: '10px 0' }}>
Item {index + 1}
</div>
))}
{hasMore && <p>Loading more items...</p>}
</div>
);
};
export default InfiniteScroll;
2. Key Components:
State (
items
): Holds the list of items to display. Initially, it starts with a set number of items (20 in this case).State (
hasMore
): Tracks whether more items can be loaded.Effect (
useEffect
): Sets up an event listener for the scroll event when the component mounts and cleans it up when the component unmounts.Scroll Handler (
handleScroll
): Checks if the user has scrolled to the bottom of the page and triggers loading more items if true.Loading More Items (
loadMoreItems
): Simulates an API call by adding more items to the list with a delay.
3. Behavior:
Condition Check:
- The
if
condition checks if the user has scrolled near the bottom of the page. Specifically, it checks if the sum of the viewport height (window.innerHeight
) and the vertical scroll position (document.documentElement.scrollTop
) is greater than or equal to the total height of the document minus 100 pixels (document.documentElement.offsetHeight - 100
).
- The
Early Return:
No Loading: If the condition is met, meaning the user is within 100 pixels of the bottom of the page, the function immediately returns and does not call
loadMoreItems()
.Loading More: If the condition is not met, the function proceeds to call
loadMoreItems()
, which would load additional items.
4. Rendering the Component:
You can render this component in your app by importing and using it in your main component:
import React from 'react';
import ReactDOM from 'react-dom';
import InfiniteScroll from './InfiniteScroll';
ReactDOM.render(<InfiniteScroll />, document.getElementById('root'));
This basic implementation can be expanded with real API calls, loading indicators, and more sophisticated logic for stopping the scroll when no more items are available.
Subscribe to my newsletter
Read articles from Tushar Khanna directly inside your inbox. Subscribe to the newsletter, and don't miss out.
Written by
Tushar Khanna
Tushar Khanna
JS Enthusiast