javascript

How to Implement Infinite Scroll with JavaScript and APIs

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.


Why Use Infinite Scroll?

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.


Setting Up Infinite Scroll

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:

  1. HTML Structure to hold the content.
  2. CSS for styling the loading indicator.
  3. JavaScript to fetch data and manage the scroll event.

Step 1: HTML Structure

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>
  • #content-container: This div will hold all the content fetched from the API.
  • #loading: This div appears at the bottom of the page while new data is being fetched.

Step 2: CSS for Styling

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.


Step 3: Fetch Data with JavaScript

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';
}
  • fetchData(): Fetches a limited number of posts (5 here) from the JSONPlaceholder API for each page.

Step 4: Adding Infinite Scroll

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();
  • scrollTop: How far the user has scrolled.
  • clientHeight: Visible height of the viewport.
  • scrollHeight: Total height of the page.

When scrollTop + clientHeight is close to scrollHeight, it’s time to load more data. We then call fetchData() again, which loads new posts.


Step 5: Add Loading Indicator

To improve the user experience, we’ve included a loading indicator. This will show up while new data is being fetched:

  1. We set #loading to display: block when data fetch begins.
  2. After the data is appended, we hide #loading again.

Complete Code

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();

Wrapping Up

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

Recent Posts

AWS Expands Payment Options for Nigerian Customers, Introducing Naira (NGN) for Local Transactions

Amazon Web Services (AWS) continues to enhance its customer experience by offering more flexible payment…

2 days ago

Why JavaScript Remains Dominant in 2025

JavaScript, often hailed as the "language of the web," continues to dominate the programming landscape…

3 days ago

Amazon Moves to Upgrade Alexa with Generative AI Technology

Amazon is accelerating efforts to reinvent Alexa as a generative AI-powered “agent” capable of performing…

4 days ago

Smuggled Starlink Devices Allegedly Used to Bypass India’s Internet Shutdown

SpaceX's satellite-based Starlink, which is currently unlicensed for use in India, is reportedly being utilized…

5 days ago

Why Netflix Dumped React For its Frontend

Netflix, a pioneer in the streaming industry, has always been at the forefront of adopting…

5 days ago

Microsoft Files Lawsuit Against Hacking Group Misusing Azure AI for Malicious Content Generation

Microsoft has announced legal action against a 'foreign-based threat actor group' accused of running a…

1 week ago