I have long wanted to talk about how infinite scroll functionality can be implemented in a list of items that might be on any Web page. Infinite scroll is a technique that allows the user to interact with the mouse by scrolling down to load new dynamic content. In this way, the scroll becomes infinite and the initial load time improves considerably. Not going too far, for example, an Ecommerce platform has to display products by categories if or if not. Normally, they usually work with pagination either with PHP or JavaScript. Have you ever wondered what it would be like to paginate products with infinite scroll?
The infinite scroll is also used by platforms such as Facebook, Twitter or Tik Tok to display news or publications as you scroll with the mouse.
Social networks are an ideal scenario, at least they have accustomed us to that but, perhaps if there was a pagination on these websites with so much content that requires user clicks to display more information, it is more likely that they end up getting tired and do not browse as much.
One-page websites are becoming more and more trendy and it is no coincidence. Don't you get the feeling that infinite scroll improves navigation?
Infinite scroll can be an excellent resource to show your content but you must use it correctly. Before you decide lightly that you want to use infinite scroll, you must take into account its advantages and disadvantages.
Advantages of infinite scroll
It makes the users to be pending and this increases the navigation time.
- Increases session time.
- It has been studied that users reach elements that they would never reach with pagination.
- Perfect for touch screens.
- Ideal for mobile devices.
- Ideal for visual content.
- It is more attractive and modern.
Disadvantages of infinite scroll
- Problems with the footer that is practically not shown until the end of the content.
- Non-existent content organization.
- Finding a specific element is difficult. For example, in classic pagination it is possible to access a page to access an element.
- Time problems with loading large images in each iteration.
- In this article you will learn how to implement an infinite scroll system in your web page using just JavaScript and asynchronous calls to the server.
HTML code
In the template or HTML file I am just going to add an empty list of elements:
<ul class="items row"></ul>
For the visual part, I will rely on Bootstrap 4 design.
So I am declaring an unordered list <ul>
with the .row class to define a row.
The items class I will use to access the list via JavaScript.
JavaScript code
Pay attention to this section because the key to the matter is to understand the JavaScript code which is ultimately the conduit that queries the data from the server to display them on the screen.
var start = 0; var limit = 12; var endItems = false; window.addEventListener('scroll', () => { if (window.scrollY == document.documentElement.scrollHeight - window.innerHeight) { getItems(); } }); window.onload = function() { getItems(); } function getItems() { if (endItems) { return; } let params = new FormData(); params.append('start', start); params.append('limit', limit); fetch('ajax.php', { method: 'post', body: params, }).then(function(response) { if (response.ok) { return response.json(); } else { throw 'Server call error'; } }).then(function(items) { if (items.endItems) { endItems = true; } else { var html = ''; items.forEach(function(element) { html += ` <li class="col-lg-3"> <div class="card mb-3"> <div class="card-body"> <h5 class="card-title">${element.name}</h5> <p class="card-text">${element.description}</p> <p class="card-text">Qty: ${element.quantity}</p> <p class="card-text">Price: ${element.price} €</p> <p class="card-text">Total: ${element.price * element.quantity} €</p> <a href="#" class="btn btn-primary">Buy now</a> </div> </div> </li> `; }); const current_items = document.querySelector(".items"); current_items.innerHTML += html; start += limit; } }).catch(function(error) { console.log(error); }); }
In this code I am defining 3 global variables:
start: to define the start of the SQL query boundary in the database. Initially, we start it at 0
to get the first records. This variable will change its value as we scroll with the mouse.
limit: it is used to define the number of elements per page. In this case we want it to be 12 to show 3 rows in 4 columns.
endItems: it is a boolean variable that I use to identify when we are at the end of the list of elements. Initially, it starts with false.
Next, we capture the scroll event to check when we have reached the bottom with the following code snippet:
window.addEventListener('scroll', () => { if (window.scrollY == document.documentElement.scrollHeight - window.innerHeight) { getItems(); } })
The function getItems()
is the one that will be in charge of fetching the information from the server to return the items that touch.
Logically, as we have defined our empty list in the HTML, when loading the page we will also call our getItems()
function:
window.onload = function() { getItems();}
In the function getItems()
the first thing we do is to check if we have reached the end of the list. If so, we stop the execution.
if (endItems) { return; }
Otherwise, we prepare the parameters we want to send to the server with:
let params = new FormData(); params.append('start', start); params.append('limit', limit);
To make the call to the server I use fetch as follows:
fetch('ajax.php', { method: 'post', body: params, }).then(function(response) { if (response.ok) { return response.json(); } else { throw 'Server call error'; } }).then(function(items) { if (items.endItems) { endItems = true; } else { var html = ''; items.forEach(function(element) { html += ` <li class="col-lg-3"> <div class="card mb-3"> <div class="card-body"> <h5 class="card-title">${element.name}</h5> <p class="card-text">${element.description}</p> <p class="card-text">Qty: ${element.quantity}</p> <p class="card-text">Price: ${element.price} €</p> <p class="card-text">Total: ${element.price * element.quantity} €</p> <a href="#" class="btn btn-primary">Buy now</a> </div> </div> </li> `; }); const current_items = document.querySelector(".items"); current_items.innerHTML += html; start += limit; } }).catch(function(error) { console.log(error); });
The JavaScript fetch function provides an interface to access and manipulate parts of the HTTP channel through requests and responses. Something very similar to Ajax or XMLHttpRequest but in a modern version.
In this case we pass a "post" method and a body with the parameters that we want to transfer to the server.
Once the data is sent, we then capture the response from the server.
If the response is correct, we return the response with json.
Otherwise, we would show the user a server error.
We use then again to receive the data from the server, in this case, the new items or the indicated boolean variable.
If we have not reached the end, we show the items arriving from the server.
PHP code
In the ajax.php file being invoked in the fetch we have the following:
try { $connexion = new PDO( "mysql:host=your-website.com;dbname=databasename", "user", "password", array(PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION, PDO::MYSQL_ATTR_INIT_COMMAND => "SET NAMES utf8") ); } catch (PDOException $e){ echo $e->getMessage(); } $start = $_POST['start']; $limit = $_POST['limit']; try { $statement = $connexion->prepare( 'SELECT * FROM products ORDER BY products_id DESC LIMIT '.(int)$start.','.(int)$limit ); $statement->setFetchMode(PDO::FETCH_ASSOC); $statement->execute(); $items = $statement->fetchAll(); if (is_array($items) && count($items) > 0) { die(json_encode($items)); } else { die(json_encode(array('reachedMax' => true))); } } catch (PDOException $e){ die(json_encode(array('error' => $e->getMessage()))); }
We make an attempt to connect to the database with PDO where basededatos must be the name of your database, user must be the user name of the database and password must be the password to access the database.
If it succeeds in connecting to the database, we receive the parameters start and limit to try to execute the query based on these parameters.
If the query returns information, we return to the JavaScript the array of elements to be displayed.
If the query returns the endItems variable true, the execution is finished and now the getItems() function will not execute the asynchronous call.
Conclusion
The infinite scroll can be a very good resource for your website if used in the right way.
For some projects it is indispensable or required but for others it can be optional.
Based only on its advantages and disadvantages I think it is worth implementing it.
What do you think?