Implementacja nieskończonego przewijania na stronie internetowej
Nieskończone przewijanie to mechanizm, który umożliwia dynamiczne doładowywanie treści w miarę przewijania strony przez użytkownika. Eliminuje potrzebę tradycyjnego podziału na strony z przyciskami nawigacyjnymi. Takie rozwiązanie zapewnia bardziej intuicyjną i płynną nawigację, zwłaszcza na urządzeniach mobilnych.
W niniejszym artykule omówimy, jak wdrożyć nieskończone przewijanie, wykorzystując podstawowe technologie internetowe: HTML, CSS i JavaScript.
Konfiguracja warstwy prezentacji
Pierwszym krokiem jest stworzenie szkieletu HTML, który będzie wyświetlał treść. Poniżej przedstawiono przykładowy kod:
<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>
Powyższy fragment przedstawia kontener, w którym umieszczone są przykładowe obrazy. Kod odwołuje się również do zewnętrznych arkuszy stylów CSS i plików JavaScript, które zostaną omówione w dalszej części artykułu.
Stylizacja CSS dla przewijalnej zawartości
Aby poprawnie wyświetlić elementy (w tym przypadku obrazki) w formie siatki, należy odpowiednio ostylować stronę za pomocą CSS. Poniższy kod powinien zostać umieszczony w pliku `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%); }
Dzięki tym stylom obrazki będą wyświetlane w trzech kolumnach, a dodatkowo dodany jest prosty styl dla wskaźnika ładowania.
W tym momencie strona powinna prezentować się podobnie do:
Logika nieskończonego przewijania w JavaScript
Kluczowym elementem wdrożenia nieskończonego przewijania jest kod JavaScript. Edytuj plik `script.js` i umieść w nim następujący kod:
"use strict"; window.addEventListener("scroll", () => { if ( window.scrollY + window.innerHeight >= document.documentElement.scrollHeight - 100 ) { fetchMoreContent(); } });
Ten fragment kodu nasłuchuje zdarzenia przewijania strony i uruchamia funkcję `fetchMoreContent()`, gdy użytkownik zbliży się do dolnej krawędzi strony (dokładnie 100 pikseli przed jej końcem).
Kolejny kod dotyczy funkcji, która pobiera dane:
async function fetchMoreContent() { try { let response = await fetch("https://fakestoreapi.com/products?limit=3"); if (!response.ok) { throw new Error("Network response was not ok"); } let data = await response.json(); console.log(data); } catch (error) { console.error("There was a problem fetching new content:", error); } finally { console.log("Fetch function fired"); } }
Funkcja ta pobiera z API fakestoreapi trzy nowe elementy (w tym przypadku są to produkty). W konsoli przeglądarki powinny pojawiać się pobrane dane.
Aby uniknąć nadmiernego obciążania serwera i przeglądarki poprzez wielokrotne wywoływanie funkcji pobierającej dane, warto wprowadzić dodatkową zmienną, która będzie informowała, czy aktualnie trwa pobieranie:
let isFetching = false;
Teraz należy zmodyfikować funkcję pobierającą dane, aby pobierała je dopiero po zakończeniu poprzedniej operacji:
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("Network response was not ok"); } let data = await response.json(); } catch (error) { console.error("There was a problem fetching new content:", error); } finally { console.log("Fetch function fired"); isFetching = false; } }
Prezentacja pobranych danych
Po pobraniu danych konieczne jest ich wyświetlenie. W tym celu należy pobrać referencję do elementu nadrzędnego (kontenera), w którym umieszczane będą nowe obrazki:
const productsList = document.querySelector(".products__list");
Następnie należy stworzyć funkcję, która na podstawie pobranych danych wygeneruje elementy HTML i doda je do kontenera:
function displayNewContent(data) { data.forEach((item) => { const imgElement = document.createElement("img"); imgElement.src = item.image; imgElement.alt = item.title; productsList.appendChild(imgElement); }); }
Ostatnim krokiem jest zmodyfikowanie funkcji `fetchMoreContent()` tak, aby po pobraniu danych przekazała je do funkcji `displayNewContent()`:
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("Network response was not ok"); } let data = await response.json(); displayNewContent(data); } catch (error) { console.error("There was a problem fetching new content:", error); } finally { console.log("Fetch function fired"); isFetching = false; } }
Po tych zmianach nieskończone przewijanie powinno działać prawidłowo, a nowe elementy będą pojawiać się w miarę przewijania strony.
Aby podnieść komfort użytkowania, warto dodać wskaźnik ładowania, który będzie informował użytkownika o trwającym procesie pobierania danych. Zacznijmy od dodania do HTML elementu wskaźnika:
<h1 class="loading-indicator">Ładowanie...</h1>
Następnie pobierzmy do niego referencję w JS:
const loadingIndicator = document.querySelector(".loading-indicator");
Teraz stwórzmy dwie funkcje, które będą kontrolować widoczność wskaźnika:
function showLoadingIndicator() { loadingIndicator.style.display = "block"; console.log("Ładowanie..."); } function hideLoadingIndicator() { loadingIndicator.style.display = "none"; console.log("Zakończono ładowanie."); }
Na koniec zmodyfikuj funkcję `fetchMoreContent`, aby pokazywała wskaźnik na czas pobierania danych i ukrywała go po zakończeniu:
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("Network response was not ok"); } let data = await response.json(); displayNewContent(data); } catch (error) { console.error("There was a problem fetching new content:", error); } finally { console.log("Fetch function fired"); hideLoadingIndicator(); isFetching = false; } }
Wprowadzone zmiany spowodują, że w trakcie ładowania nowych treści, użytkownik będzie widział wskaźnik „Ładowanie…”.
Warto pamiętać o kilku dobrych praktykach przy implementacji nieskończonego przewijania:
- Unikaj pobierania zbyt dużej ilości danych na raz, gdyż może to negatywnie wpłynąć na wydajność przeglądarki.
- Zastosuj funkcję opóźniającą (debounce) przy zdarzeniu przewijania, aby nie wysyłać zbyt wielu żądań w krótkim czasie.
- Daj użytkownikowi wybór, czy chce korzystać z nieskończonego przewijania, czy tradycyjnej paginacji.
- Poinformuj użytkownika, jeśli nie ma już więcej treści do załadowania.
Podsumowanie
Nieskończone przewijanie jest wygodnym rozwiązaniem, które ułatwia przeglądanie treści. Szczególnie sprawdza się w przypadku stron mobilnych. Wykorzystując omówione techniki i wskazówki, można łatwo wdrożyć tę funkcjonalność na swojej witrynie.
Zawsze należy pamiętać o perspektywie użytkownika i zapewnić mu informacje o aktualnym stanie działania aplikacji, np. poprzez wyświetlanie wskaźników ładowania czy komunikatów o błędach.
newsblog.pl