DEV Community

Cover image for How to create Infinite Scroll with Svelte
Nelson Hernández
Nelson Hernández

Posted on • Updated on

How to create Infinite Scroll with Svelte

For this example we will use the Intersection Observer API

Component in svelte

<script>
  import axios from "axios";
  import { infiniteScroll } from "../../functions/infiniteScroll";

  let pageNumber = 0;
  let characters = [];
  let Loading = false;

  const fetchData = async () => {
    try {
      Loading = true;
      const response = await axios({
        method: "GET",
        url: "https://rickandmortyapi.com/api/character/",
        params: { page: pageNumber },
      });
      // SAVE NEW RESULTS
      characters = [
        ...new Set([...characters, ...response.data.results.map((b) => b)]),
      ];
      Loading = false;
    } catch (error) {
      console.log(error);
    }
  };
  const load = () => {
    setTimeout(() => {
      pageNumber = pageNumber + 1;
      fetchData();
    }, 300); // WE WAITED A FEW SECONDS
  };
  // REACTIVE DECLARATIONS
  let elementRef = null;
  $: {
    if (elementRef) {
      infiniteScroll({ fetch: load, element: elementRef });
    }
  }
</script>

<div class="box-shawdow">
  {#each characters as character}
  <div class="grid-games">
    <div class="box-game">
        {character.name}
      </div>
    </div>
  {/each}

  {#if Loading}
    <h1>Cargando...</h1>
  {/if}
<!-- ELEMENT OBSERVER -->
  {#if Loading === false}
    <li bind:this={elementRef}>Cargando</li>
  {/if}
</div>
Enter fullscreen mode Exit fullscreen mode

Function of Intersection Observer

export const infiniteScroll = ({ fetch, element }) => {
  if (element) {
    const observer = new IntersectionObserver(
      (entries) => {
        const first = entries[0];
        if (first.isIntersecting) {
          console.log("Is Intersecting");
          fetch();
        }
      },
      { threshold: 1 }
    );
    observer.observe(element);//Element of DOM
  }
};
Enter fullscreen mode Exit fullscreen mode

Code of example in Github 🔗

Top comments (1)

Collapse
 
woss profile image
woss

{ threshold: 1 } should be { threshold: [0,1.0] }