Paginacja w Vanilla JavaScript

Paginacja w Vanilla JavaScript

Wprowadzenie

Podczas tworzenia strony internetowej lub aplikacji internetowej, zwłaszcza jeśli zawierają one dużo szablonowy zawartość (taką jak siatka lub lista elementów należących do kategorii) – ogólnie jest to dobry pomysł podziel go na strony aby zmniejszyć liczbę elementów wyświetlanych jednocześnie na ekranie.

W tym artykule dowiemy się, jak od podstaw zaimplementować paginację w naszych projektach internetowych przy użyciu Vanilla JavaScript.

Na potrzeby tego artykułu pobierzemy treść z to przykładowa odpowiedź API. Zawiera 100 punktów danych, ale użyjemy tylko 30 i wyświetlimy jednocześnie 6 postów na naszym ekranie.

paginacja-w-animacji-javascript

Pierwsze kroki

Przed pobraniem wszystkich wymaganych postów z interfejsu API za pomocą wbudowanego w przeglądarkę interfejsu Fetch API musimy najpierw utworzyć podstawowy znacznik HTML, który zostanie później dynamicznie wypełniony za pomocą naszego skryptu:

<div class="container"> <div class="title-section"> <h1 class="title">Posts</h1> </div> <div class="posts-section"></div> <div class="pagination-section"> <ul class="pagination"> <li class="page-item prev"><a class="page-link" href="#">Previous</a></li> <li class="page-item next"><a class="page-link" href="#">Next</a></li> </ul> </div>
</div>

Pobieranie postów API REST

Jak wspomniano wcześniej, paginacja polega na dzieleniu treści na mniejsze części. Wymaga pobrania danych, decydowania, kiedy i jak podzielić, obliczenia liczby stron, a następnie pokazania ich części użytkownikowi. Na szczęście – funkcjonalność zaplecza zwykle zajmuje się kilkoma pierwszymi zadaniami i zwraca odpowiednią stronę, całkowitą liczbę stron i treść na stronę.

Uwaga: W zależności od konkretnego interfejsu API, z którym pracujesz — leniwe ładowanie wyników może być możliwe lub nie. Jeśli to możliwe – preferuj leniwe ładowanie wyników zamiast ładowania ich wszystkich z góry. Większość nowoczesnych interfejsów API jest zgodna z praktykami, które umożliwiają ustawianie limit or page count i zwróć całkowitą liczbę stron, które możesz wyświetlić użytkownikowi.

Zacznijmy od pobrania wszystkich naszych postów, a później zmienimy to, aby wysyłać zapytania tylko do kilku punktów danych na stronę:

const postsSection = document.querySelector(".posts-section"); const fetchPosts = async () => { const response = await fetch( "https://jsonplaceholder.typicode.com/posts" ); const posts = await response.json(); postsSection.innerHTML = ""; posts.forEach((post) => { postsSection.innerHTML += ` <div class="posts-card"> <div class="post-title"> <h2 class="post-title-text">${post.title}</h2> </div> <div class="post-body"> <p class="post-body-text"> ${post.body} </p> </div> </div> `; });
}; fetchPosts();

Przeanalizujmy szybko powyższy kod. Przede wszystkim zaczęliśmy od zdobycia tzw div element, w którym będziemy wyświetlać całą naszą zawartość za pośrednictwem class nazwa, którą przypisaliśmy do div. Na koniec napisaliśmy funkcję obsługującą operację pobierania.

W fetchPosts() funkcji, użyliśmy Fetch API aby pobrać posty z JSON Placeholder publikuje interfejs API, a następnie zapisz dane JSON, do których odwołuje się plik posts zmienna i użył innerHTML właściwość, aby dodać każdy element zawartości do pliku posts-section przechodząc przez nie w pętli.

W tym momencie pomyślnie pobraliśmy całą naszą zawartość.

Uwaga: Możesz także pobrać zawartość przy użyciu innej metody, ale upewnij się, że cała treść jest załadowana na tej stronie, zanim przejdziemy do tworzenia podziału na strony.

Zacznijmy od zadeklarowania trzech zmiennych, które są krytyczne dla zaimplementowania podziału na strony na naszej stronie internetowej. Pierwszym z nich jest liczbę postów, które chcemy zadeklarować na stronę, a później aktualny numer strony (1 domyślnie) i łączna liczba stron.

Uwaga: Podczas korzystania z danych z początkowego interfejsu API i bazy danych plik całkowita liczba stron lub punktów danych jest zwykle zwracana. Jeśli nie otrzymamy całkowitej liczby stron, można to obliczyć na podstawie całkowitej liczby obiektów i rozmiaru strony.

W tym przewodniku damy łączna liczba stron ustalona liczba 30:

const numberPerPage = 6;
var pageNumber = 1;
var numberOfPages = 30;

W poprzedniej sekcji wyświetlaliśmy wszystkie posty na jednej stronie, ale chcemy wyświetlić tylko sześć naraz. Dlatego ustawiliśmy numberPerPage do 6 którego teraz użyjemy do dostosowania operacji pobierania, aby tylko się wyświetlała 6 posty.

Zależy to od konkretnej implementacji, ale powszechną praktyką jest zezwalanie na używanie parametrów zapytań podczas pobierania wyników z interfejsów API, które umożliwiają pobieranie określonego strona wyników. Na przykład próbny interfejs API REST, którego używamy, pozwala na page i limit parametry, które pozwalają ładować tylko te partie, które będą wyświetlane w danym momencie.

W ten sposób ładujemy tylko te dane, które chcemy pokazać użytkownikowi! Następnie możemy albo pobrać następną stronę z wyprzedzeniem, aby skrócić czas ładowania, albo rozkoszować się przyspieszeniem obliczeniowym osiągniętym dzięki załadowaniu tylko danych do wyświetlenia.

Będziemy korzystać z tych parametrów, zmieniając nasze żądanie pobierania:

const fetchPosts = async (pageNumber) => { const response = await fetch( `https://jsonplaceholder.typicode.com/posts?_page=${pageNumber}&_limit=${numberPerPage}` ); const posts = await response.json(); postsSection.innerHTML = ""; posts.forEach((post) => { postsSection.innerHTML += ` <div class="posts-card"> <div class="post-title"> <h2 class="post-title-text">${post.title}</h2> </div> <div class="post-body"> <p class="post-body-text"> ${post.body} </p> </div> </div> `; });
}; fetchPosts();

W powyższym kodzie dodaliśmy dwa parametry do punktu końcowego interfejsu API, którymi są pageNumber oraz liczba postów na stronę co pomogłoby nam podzielić nasze posty na kilka stron, a następnie te posty mogą być teraz wyświetlane na podstawie numeru strony.

Dodatkowo zdaliśmy również w pageNumber do fetchPosts() funkcję, abyśmy mogli wywołać tę funkcję za każdym razem, gdy strona się zmieni:

javascript-paginacja-bez-nawigacji

Dodajmy teraz funkcjonalność do przycisków nawigacyjnych na dole naszej strony i niech wyświetlają odpowiednią treść na podstawie numeru strony.

Zauważmy, że w znacznikach mieliśmy sekcję pokazującą przyciski stronicowania:

<div class="pagination-section"> <ul class="pagination"> <li class="page-item prev"><a class="page-link" href="#">Previous</a></li> <li class="page-item next"><a class="page-link" href="#">Next</a></li> </ul>
</div>

Teraz będziemy dodawać click zdarzenia do każdego przycisku, tak aby po ich kliknięciu wyświetlała się treść przeznaczona dla tej strony.

Wdrażanie Poprzednie Przycisk

Logika tutaj jest dość prosta. Wszystko, co musimy zrobić, to pobrać element reprezentujący poprzedni przycisk, Dodaj click słuchacz zdarzeń i wyświetla odpowiednią treść po kliknięciu przycisku:

Zapoznaj się z naszym praktycznym, praktycznym przewodnikiem dotyczącym nauki Git, zawierającym najlepsze praktyki, standardy przyjęte w branży i dołączoną ściągawkę. Zatrzymaj polecenia Google Git, a właściwie uczyć się to!


const prev = document.querySelector('.prev');
prev.addEventListener('click', (e) => { e.preventDefault(); if (pageNumber > 1) { pageNumber--; fetchPosts(pageNumber); }
});

Po dodaniu A click detektor zdarzeń, sprawdziliśmy, czy bieżący numer strony jest większy niż 1 w funkcji oddzwaniania. Jeśli liczba jest równa lub mniejsza niż 1, będziemy nadal pokazywać bieżącą zawartość. Ale jeśli bieżący numer strony jest większy niż 1 możemy dowolnie zmniejszać jego wartość i nazywać fetchPosts(pageNumber) funkcji z nowym numerem strony przekazanym jako argument, pokazując tym samym zawartość poprzedniej strony.

Wdrażanie Następna Przycisk

Logika tutaj jest całkowicie taka sama jak w przypadku poprzedni przycisk, z kilkoma drobnymi zmianami. Oczywiście pobierzemy element listy razem z klasą next zamiast prev. Sprawdzimy również, czy bieżący numer strony jest mniejszy niż Numer stron do którego się nastawiliśmy 30 ręcznie wcześniej. Na koniec zwiększymy bieżący numer strony zamiast go zmniejszać:


const next = document.querySelector(".next");
next.addEventListener("click", (e) => { e.preventDefault(); if (pageNumber < numberOfPages) { pageNumber++; fetchPosts(pageNumber); }
});

Wnioski

Podział treści na mniejsze, łatwiejsze w zarządzaniu fragmenty, które są wyświetlane pojedynczo, ma kluczowe znaczenie za każdym razem, gdy próbujesz wyświetlić bazę danych lub inne źródło danych w aplikacji internetowej.

W tym artykule przyjrzeliśmy się, jak zaimplementować paginację za pomocą JavaScript od podstaw, bez żadnych zewnętrznych bibliotek i narzędzi.

Znak czasu:

Więcej z Nadużycie stosu