The infinite scroll layout is inspired by websites like Facebook and Twitter. This is just pagination where as the user scrolls to the bottom of the page, more content loads. This improves the user experience on the website by making sure there is more and more content on the page for users to read.
Performing infinite scroll pagination on the right
When infinite scrolling pagination is implemented, there are some really important points to remember.
1. Don’t put important links at the bottom
Important links should not be at the bottom of the page. This is because every time the user tries to scroll down to find them, a new set of entries will be loaded. All important links should be pinned to a sidebar or kept permanently at the top.
2. Plan ahead
It’s important to plan ahead: where you want to include the pagination and how you will process it. A common way to do pagination is to list page numbers at the bottom of the page. Using the infinite scroll method, however, will no longer display page numbers at the end of the item list, as they are no longer needed. This layout can be used on all themes as long as you don’t include a lot of information in the footer section, as it may not give the desired effect.
In this tutorial we will learn how to implement the infinite scroll function in Javascript.
The page will display a list of fun facts about cats, which will come from an API. The API returns 10 fun facts by default. When you scroll to the bottom of the page, the application will display an indicator to indicate the loading status of the app. Meanwhile, the app will call the API to load the next batch of fun facts.
We will use this url to upload fun facts. The API accepts a query string: page
which tells the API which page to load.
https://catfact.ninja/facts?page=${page}&limit=${limit}
Now, let’s start with the application.
1. Create the project structure
First, create a folder with the following structure.
root -- index.html -- style.css -- app.js
2. Create the HTML file
We will have several sections in our HTML file. A container
, where the entire scrollable list of fun facts will be displayed. A quotes
section for each fun fact. And there will be a loader
, which will be visible when loading the curiosities. The loader
it will be invisible by default.
<div class="container"> <h1>Fun Facts about Cats</h1> <div class="facts"> </div> <div class="loader"> <div></div> <div></div> <div></div> </div> </div>
3. Build the script
Next, we need to create a script, which will link with the div and load the fun fact. To achieve this, we will use the querySelector()
.
const factsEl = document.querySelector('.facts'); const loader = document.querySelector('.loader');
We also need a few control variables to define which set of elements will be shown on the screen. The control variables in this code snippet are:
-
currentPage
: The current page is initialized to 1. When scrolling to the bottom of the page, the current page will be incremented by 1 and an API request will be made to get the content of the next page. When the page is scrolled up, the current page will be decremented by 1. -
total
: This variable stores the total number of mentions returned by the Fun Facts API.
4. Build the getFacts
function
The role of getFacts
function is to call the API and return the fun fact. The getFacts
function takes a single argument: page
. Use the Fetch API mentioned above to fetch data for infinite scrolling.
Fetch
always returns a promise
so we will use the await-async
syntax for receiving and processing the response. Take the json
data, we will use the json
()
function. The getFacts
function would return a promise, which it will resolve and return the JSON.
const getfacts = async (page, limit) => { const API_URL = `https://catfact.ninja/facts?page=${page}&limit=${limit}`; const response = await fetch(API_URL); // handle 404 if (!response.ok) { throw new Error(`An error occurred: ${response.status}`); } return await response.json(); }
5. Build the showFacts
function
Now that we’ve got the fun facts, where would we show them? This is why we must have a showFacts
function. The showFacts
function works by iterating through the facts
Vector. Then use the template literal
syntax for creating an HTML representation of a fact
object.
const showfacts = (facts) => { facts.forEach(fact => { const factEl = document.createElement('blockfact'); factEl.classList.add('fact'); factEl.innerHTML = ` ${fact.fact} `; factsEl.appendChild(factEl); }); };
A sample of the generated blockFact
element is:
<blockfact class="fact"> Unlike dogs, cats do not have a sweet tooth. Scientists believe this is due to a mutation in a key taste receptor. </blockfact>
We use the appendChild
function to add the <blockfact>
element to container.
6. Show and hide the loading indicator
When the user reaches the bottom of the page, a loading indicator should be shown. For this, we will introduce two functions. One for loading and one for hiding the magazine. We would use opacity: 1
to show the loader. AND, opacity: 0
to hide the charger. Addition and removal opacity
will show/hide the loader, respectively.
const hideLoader = () => { loader.classList.remove('show'); }; const showLoader = () => { loader.classList.add('show'); };
7. Check out more fun facts
To ensure performance, we will introduce a function that can check if the API has multiple facts. The hasMoreFacts()
the function would return true
if there are more items to recover. If there are no more items to fetch, the API calls will stop.
const hasMorefacts = (page, limit, total) => { const startIndex = (page - 1) * limit + 1; return total === 0 || startIndex < total; };
8. Encode the loadFacts
function
The loadFacts
The function is responsible for performing four important actions:
- show or hide the loading indicator
- call
getFacts
function to retrieve more facts. - show the facts
const loadfacts = async (page, limit) => { // show the loader showLoader(); try { // if having more facts to fetch if (hasMorefacts(page, limit, total)) { // call the API to get facts const response = await getfacts(page, limit); // show facts showfacts(response.data); // update the total total = response.total; } } catch (error) { console.log(error.message); } finally { hideLoader(); } };
In one sense, a disadvantage of this implementation is its speed of execution. You won’t see the loading indicator, most of the time, because the API can come back really fast. If you want to see the loading indicator with every swipe, a setTimeout
function can be used. By changing the delay
of yours setTimeout
the function will decide how long the loading indicator will be displayed.
9. Handle scroll events
When the user scrolls to the bottom of the page a scroll event handler
you need to call the loadFacts
function. The function will be called if all of the following conditions are met:
- the parchment has reached the bottom of the page
- there are more facts to load
To get the scroll event, we’ll use three window properties:
-
window.scrollHeight
gives the height of the whole document -
window.scrollY
provides an account of how far the document has been scrolled by the user. -
window.innerHeight
gives the height of the visible window
The diagram below provides a better overview of the above properties. Also you will be able to understand that, if the sum of innerHeight
And scrollY
are also equal to or greater than scrollHeight
the end of the document is reached and it is at this point that more fun facts need to be loaded.
window.addEventListener('scroll', () => { const { scrollTop, scrollHeight, clientHeight } = document.documentElement; if (scrollTop + clientHeight >= scrollHeight - 5 && hasMoreFacts(currentPage, limit, total)) { currentPage++; loadFacts(currentPage, limit); } }, { passive: true });
10. Initialize the page
The last step in our Infinite Scroll would be to initialize the page. It’s important to call loadFacts
to load the very first batch of fun facts.
loadfacts(currentPage, limit);
Live demonstration
Conclusion
Now, we’ve implemented a simple infinite scroll in Javascript, which will fetch and display fun facts about cats, every time the user scrolls. This is just one of the more commonly used methods for infinite scrolling.