Како имплементирати бесконачно померање у веб апликацији

Beskonačno skrolovanje omogućava da se sadržaj neprekidno učitava dok korisnici pregledaju stranicu, za razliku od tradicionalnog paginiranja koje zahteva klik na dugme za učitavanje. Ova funkcija može znatno poboljšati korisničko iskustvo, posebno na mobilnim telefonima.

U ovom vodiču saznaćete kako da implementirate beskonačno skrolovanje koristeći osnovne tehnologije: HTML, CSS i JavaScript.

Postavljanje frontenda

Počnite sa osnovnom HTML strukturom kako biste prikazali vaš sadržaj. Primer HTML koda:

<link rel="stylesheet" href="https://wilku.top/how-to-implement-infinite-scroll-in-a-web-application/style.css" />
<h1>Stranica sa beskonačnim skrolovanjem</h1>
<div class="products__list">
<img src="https://fakestoreapi.com/img/71li-ujtlUL._AC_UX679_.jpg" />
<img src="https://fakestoreapi.com/img/71li-ujtlUL._AC_UX679_.jpg" />
<img src="https://fakestoreapi.com/img/71li-ujtlUL._AC_UX679_.jpg" />
<img src="https://fakestoreapi.com/img/71li-ujtlUL._AC_UX679_.jpg" />
<img src="https://fakestoreapi.com/img/71li-ujtlUL._AC_UX679_.jpg" />
<img src="https://fakestoreapi.com/img/71li-ujtlUL._AC_UX679_.jpg" />
</div>
<script src="https://wilku.top/how-to-implement-infinite-scroll-in-a-web-application/script.js"></script>

Ova stranica uključuje niz slika kao čuvare mesta i referiše na dva resursa: CSS datoteku za stilizovanje i JavaScript datoteku za logiku.

CSS stilizovanje za sadržaj koji se može skrolovati

Da biste prikazali slike čuvara mesta u mrežnom rasporedu, dodajte sledeći CSS kod u datoteku `style.css`:

* {
  margin: 0;
  padding: 0;
  box-sizing: border-box;
}

html { font-size: 62.5%; }

body {
  font-family: Cambria, Times, "Times New Roman", serif;
}

h1 {
  text-align: center;
  font-size: 5rem;
  padding: 2rem;
}

img {
  width: 100%;
  display: block;
}

.products__list {
  display: flex;
  flex-wrap: wrap;
  gap: 2rem;
  justify-content: center;
}

.products__list > * {
  width: calc(33% - 2rem);
}

.loading-indicator {
  display: none;
  position: absolute;
  bottom: 30px;
  left: 50%;
  background: #333;
  padding: 1rem 2rem;
  color: #fff;
  border-radius: 10px;
  transform: translateX(-50%);
}

U ovom trenutku, vaša stranica bi trebala izgledati otprilike ovako:

Osnovna implementacija sa JavaScriptom

Sada pređite na `script.js`. Da biste implementirali beskonačno skrolovanje, potrebno je detektovati kada korisnik skroluje do dna kontejnera sa sadržajem ili same stranice.

"use strict";

window.addEventListener("scroll", () => {
  if (
    window.scrollY + window.innerHeight >=
    document.documentElement.scrollHeight - 100
  ) {
    fetchMoreContent();
  }
});

Sledeće, kreirajte funkciju za preuzimanje više podataka sa čuvarima mesta.

async function fetchMoreContent() {
  try {
    let response = await fetch("https://fakestoreapi.com/products?limit=3");

    if (!response.ok) {
      throw new Error("Mrežni odgovor nije bio uspešan");
    }

    let data = await response.json();
    console.log(data);
  } catch (error) {
    console.error("Došlo je do problema pri preuzimanju novog sadržaja:", error);
  } finally {
    console.log("Funkcija za preuzimanje je pokrenuta");
  }
}

Za ovaj projekat možete koristiti API sa fakestoreapi.

Da biste proverili da li se vaši podaci preuzimaju tokom skrolovanja, pogledajte konzolu:

Primetićete da se podaci preuzimaju više puta tokom skrolovanja, što može negativno uticati na performanse. Da biste to sprečili, postavite inicijalno stanje za preuzimanje podataka:

let isFetching = false;

Zatim, modifikujte funkciju za preuzimanje tako da preuzima podatke samo kada je prethodno preuzimanje završeno.

async function fetchMoreContent() {
  if (isFetching) return;

  isFetching = true;

  try {
    let response = await fetch("https://fakestoreapi.com/products?limit=3");

    if (!response.ok) {
      throw new Error("Mrežni odgovor nije bio uspešan");
    }

    let data = await response.json();
  } catch (error) {
    console.error("Došlo je do problema pri preuzimanju novog sadržaja:", error);
  } finally {
    console.log("Funkcija za preuzimanje je pokrenuta");
    isFetching = false;
  }
}

Prikaz novog sadržaja

Da biste prikazali novi sadržaj kada korisnik skroluje, kreirajte funkciju koja dodaje slike u roditeljski kontejner.

Prvo, izaberite roditeljski element:

const productsList = document.querySelector(".products__list");

Zatim, kreirajte funkciju za dodavanje sadržaja.

function displayNewContent(data) {
  data.forEach((item) => {
    const imgElement = document.createElement("img");
    imgElement.src = item.image;
    imgElement.alt = item.title;
    productsList.appendChild(imgElement);
  });
}

Na kraju, izmenite funkciju za preuzimanje i prosledite preuzete podatke funkciji za dodavanje.

async function fetchMoreContent() {
  if (isFetching) return;

  isFetching = true;

  try {
    let response = await fetch("https://fakestoreapi.com/products?limit=3");

    if (!response.ok) {
      throw new Error("Mrežni odgovor nije bio uspešan");
    }

    let data = await response.json();
    displayNewContent(data);
  } catch (error) {
    console.error("Došlo je do problema pri preuzimanju novog sadržaja:", error);
  } finally {
    console.log("Funkcija za preuzimanje je pokrenuta");
    isFetching = false;
  }
}

I to je to, vaše beskonačno skrolovanje sada funkcioniše.

Da biste poboljšali korisničko iskustvo, možete prikazati indikator učitavanja prilikom preuzimanja novog sadržaja. Počnite dodavanjem sledećeg HTML koda:

<h1 class="loading-indicator">Učitavanje...</h1>

Zatim, izaberite element indikatora učitavanja.

const loadingIndicator = document.querySelector(".loading-indicator");

Na kraju, kreirajte dve funkcije za promenu vidljivosti indikatora učitavanja.

function showLoadingIndicator() {
  loadingIndicator.style.display = "block";
  console.log("Učitavanje...");
}

function hideLoadingIndicator() {
  loadingIndicator.style.display = "none";
  console.log("Učitavanje završeno.");
}

Zatim, dodajte ih u funkciju za preuzimanje.

async function fetchMoreContent() {
  if (isFetching) return;

  isFetching = true;
  showLoadingIndicator();

  try {
    let response = await fetch("https://fakestoreapi.com/products?limit=3");

    if (!response.ok) {
      throw new Error("Mrežni odgovor nije bio uspešan");
    }

    let data = await response.json();
    displayNewContent(data);
  } catch (error) {
    console.error("Došlo je do problema pri preuzimanju novog sadržaja:", error);
  } finally {
    console.log("Funkcija za preuzimanje je pokrenuta");
    hideLoadingIndicator();
    isFetching = false;
  }
}

Što daje sledeći rezultat:

Neke od najboljih praksi koje treba slediti uključuju:

  • Ne preuzimajte previše stavki odjednom. To može opteretiti pregledač i smanjiti performanse.
  • Umesto da preuzimate sadržaj odmah nakon detektovanja događaja skrolovanja, koristite funkciju za odbijanje da biste malo odložili preuzimanje. To može sprečiti prekomerne mrežne zahteve.
  • Nisu svi korisnici ljubitelji beskonačnog skrolovanja. Ponudite opciju da koriste paginaciju ako žele.
  • Ako nema više sadržaja za učitavanje, obavestite korisnika umesto da neprestano pokušavate da preuzmete još sadržaja.

Ovladavanje besprekornim učitavanjem sadržaja

Beskonačno skrolovanje omogućava korisnicima da nesmetano pregledaju sadržaj i odlično je za one koji koriste mobilne uređaje. Prateći savete iz ovog članka, možete lako dodati ovu funkcionalnost na svoje veb stranice.

Ne zaboravite da razmislite o tome kako se korisnici osećaju dok koriste vašu veb lokaciju. Prikazujte povratne informacije kao što su indikatori napretka i obaveštenja o greškama kako bi korisnici uvek bili svesni onoga što se dešava.