5

Building an Infinite Scroll Component with Intersection Observer 🚀

 6 months ago
source link: https://dev.to/vikas2426/building-an-infinite-scroll-component-with-intersection-observer-17p1
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
neoserver,ios ssh client

Cover image for Building an Infinite Scroll Component with Intersection Observer 🚀

Building an Infinite Scroll Component with Intersection Observer 🚀

Demo here

In the realm of web design, user experience is paramount. Enter infinite scroll – a game-changing solution that seamlessly loads content as users scroll, eliminating the need for traditional pagination and offering a frictionless browsing experience.

scrolling

HTML Structure:

We have a <div> element with an id="content" that contains some initial items (e.g., "Item 1", "Item 2", ...).
At the end of the content, there's a sentinel <div> with the class sentinel. This sentinel div is used as a trigger point for loading more items when it comes into view.

skeleton
<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Pagination with Intersection Observer</title>
  </head>

  <body>
    <div id="content">
      <div class="item">Item 1</div>
      <div class="item">Item 2</div>
      <div class="item">Item 3</div>
      <div class="item">Item 4</div>
      <div class="item">Item 5</div>
      <div class="item">Item 6</div>
      <div class="item">Item 7</div>
      <div class="item">Item 8</div>
      <div class="item">Item 9</div>
      <div class="item">Item 10</div>
      <div class="sentinel"></div>
      <!-- we will observe this element -->
    </div>
  </body>
</html>

CSS Styling:

Basic styling to remove default margin and padding, and to define the appearance of items and the sentinel div. 🎨

    <style>
      body {
        font-family: Arial, sans-serif;
        margin: 0;
        padding: 0;
      }

      .sentinel {
        height: 20px;
        background-color: transparent;
      }

      .item {
        border: 1px solid #ccc;
        padding: 20px;
        margin-bottom: 10px;
      }
    </style>

JavaScript:

javascript
  • We select the sentinel element using document.querySelector('.sentinel'). 🎯
  • We define options for the Intersection Observer:

    • root: The viewport. We set it to null to observe the document's viewport. 👀
    • rootMargin: Margin around the root. We set it to 0px. 📏
    • threshold: The percentage of the target element which should be visible before triggering the callback. We set it to 0.8, meaning the callback will be triggered when the sentinel element is 80% in view. 🚦
  • We define the handleIntersection function, which will be called when the sentinel element intersects with the viewport.

    • It checks if the sentinel element is intersecting with the viewport using entry.isIntersecting. 🛑
    • If it is intersecting, it calls the loadMoreItems function and stops observing the sentinel element. 🔄
  • We define the loadMoreItems function, which simulates loading more items:

    • It creates new <div> elements with the class item and adds them to the content area before the sentinel. 📦
    • After loading more items, it re-observes the sentinel element. 🔄
  • We create a new IntersectionObserver instance, passing in the handleIntersection function and options. 🕵️‍♂️
  • Finally, we observe the sentinel element using observer.observe(sentinel). 🚀

    <script>
        const content = document.getElementById("content");
        const sentinel = document.querySelector(".sentinel");
        const options = {
            root: null,
            rootMargin: "0px",
            threshold: 0.8, // Trigger when the sentinel is 80% visible
        };

        function handleIntersection(entries, observer) {
            entries.forEach((entry) => {
            if (entry.isIntersecting) {
                setTimeout(loadMoreItems, 500); // mimic async call
            }
            });
        }

        function addElements(min, max){
            for (let i = min; i <= max; i++) {
                const newItem = document.createElement("div");
                newItem.classList.add("item");
                newItem.textContent = "Item " + i;
                content.appendChild(newItem);
            }
        }
        function loadMoreItems() {
            // Simulate loading more items
            const len = content.children.length;
            content.removeChild(sentinel); // remove from current position
            addElements(len, len+5)
            content.appendChild(sentinel); // add before last 4 elements
            addElements(len+6, len+10)
        }

      const observer = new IntersectionObserver(handleIntersection, options);
      observer.observe(sentinel);
    </script>

How it Works:

  • Initially, the Intersection Observer is set up to observe the sentinel element.
  • As the user scrolls down the page, when the sentinel element comes into view (i.e., when it intersects with the viewport), the handleIntersection function is called.
  • Inside handleIntersection, we load more items and stop observing the sentinel to prevent multiple triggerings.
  • After loading more items, we re-observe the sentinel so that the process can repeat when the user scrolls further down.
  • This setup allows for a smooth and efficient implementation of pagination or infinite scroll on a web page. 🌟

Note: We removed the sentinel from its previous position and added it just before the last 4 new items, this way when user scrolls down our sentinel will be in viewport before the user sees the last 4 items and we will have time to load our next new items before user reaches the end of the list, this helps us make the user experience a little better as the user never has to wait for the next new items to load.

Demo here

Connect with me on my:

LinkedIn
GitHub
Twitter


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK