04/01/2022
Hacía mucho tiempo que quería hablar sobre como se puede implementar la funcionalidad de scroll infinito en una lista de elementos que pudiera haber en cualquier página Web.
El scroll infinito es una técnica que permite al usuario interactuar con el ratón o mouse desplazándose con el scroll hacía abajo para cargar nuevo contenido dinámico.
De esta manera, el scroll se hace infinito y el tiempo de carga inicial mejora considerablemente.
No yendo muy lejos, por ejemplo, una plataforma Ecommerce tiene que mostrar productos por categorías si o si. Normalmente, suelen funcionar con paginación ya sea con PHP o JavaScript.Te
¿Te has planteado que tal sería la paginación de productos con scroll infinito?
El scroll infinito también lo utilizan plataformas como Facebook, Twitter o Tik Tok para ir mostrando noticias o publicaciones a medida que se va avanzando con el scroll del ratón.
Las redes sociales son un escenario ideal, al menos nos han acostumbrado a eso pero, es que quizá si hubiera una paginación en estos sitios webs con tanto contenido que requiere clic del usuario para mostrar más información, es más probable que se acaben cansando y no naveguen tanto.
Las páginas webs de una sola página cada vez son más tendencia y no es casualidad.
¿No tienes la sensación de que el scroll infinito mejora la navegación?
El scroll infinito puede ser un excelente recurso para mostrar tu contenido pero debes emplearlo de forma correcta.
Antes de decidir a la ligera que deseas emplear el scroll infinito, debes tener muy en cuenta sus ventajas e inconvenientes.
En este artículo vas a aprender como implementar un sistema de scroll infinito en tu página web utilizando simplemente JavaScript y llamadas asíncronas al servidor.
En la plantilla o archivo HTML tan solo voy a agregar una lista de elementos vacía:
Para la parte visual, me apoyaré con el diseño de Bootstrap 4.
Por eso estoy declarando una lista desordenada <ul> con la clase .row para definir una fila.
La clases «items» la usaré para acceder a la lista mediante JavaScript.
Atento a este apartado porque la clave del asunto está en entender el código JavaScript que en definitiva es el conducto que consulta los datos del servidor para mostrarlos en la pantalla.
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 'Error en llamada al servidor';
}
}).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">Cantidad: ${element.quantity}</p>
<p class="card-text">Precio: ${element.price} €</p>
<p class="card-text">Total: ${element.price * element.quantity} €</p>
<a href="#" class="btn btn-primary">Comprar ahora</a>
</div>
</div>
</li>
`;
});
const current_items = document.querySelector(".items");
current_items.innerHTML += html;
start += limit;
}
}).catch(function(error) {
console.log(error);
});
}En este código estoy definiendo 3 variables globales:
A continuación, capturamos el evento de scroll para comprobar cuando hemos llegado a la parte de abajo con el siguiente trozo de código:
window.addEventListener('scroll', () => {
if (window.scrollY == document.documentElement.scrollHeight - window.innerHeight) {
getItems();
}
});La función getItems() es la que se encargará de ir a buscar al servidor la información para retornar de vuelta los elementos que tocan.
Lógicamente, como hemos definido nuestra lista vacía en el HTML, al cargar la página llamaremos también a nuestra función getItems():
window.onload = function() {
getItems();
}En la función getItems() lo primero que hacemos es comprobar si hemos llegado al final de la lista. Si es así, páramos la ejecución.
if (endItems) {
return;
}En caso contrario, preparamos los parámetros que deseamos enviar al servidor con:
let params = new FormData();
params.append('start', start);
params.append('limit', limit);Para hacer la llamada al servidor uso fetch de la siguiente manera:
fetch('ajax.php', {
method: 'post',
body: params,
}).then(function(response) {
if (response.ok) {
return response.json();
} else {
throw 'Error en llamada al servidor';
}
}).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">Cantidad: ${element.quantity}</p>
<p class="card-text">Precio: ${element.price} €</p>
<p class="card-text">Total: ${element.price * element.quantity} €</p>
<a href="#" class="btn btn-primary">Comprar ahora</a>
</div>
</div>
</li>
`;
});
const current_items = document.querySelector(".items");
current_items.innerHTML += html;
start += limit;
}
}).catch(function(error) {
console.log(error);
});La función fetch de JavaScript proporciona una interfaz para acceder y manipular partes del canal HTTP mediante peticiones y respuestas. Algo muy parecido a Ajax o XMLHttpRequest pero en versión moderna.
En este caso le pasamos un método «post» y un body con los parámetros que queremos trasladar al servidor.
Una vez enviado los datos, con then capturamos la respuesta del servidor.
Si la respuesta es correcta, retornamos la respuesta con json.
En caso contrario, mostraríamos al usuario un error de servidor.
Volvemos a usar then para recibir los datos del servidor, en este caso, los nuevos items o la variable booleana indicada.
Si no hemos llegado al fin, mostramos los elementos que llegan del servidor.
En el archivo ajax.php que se está invocando en el fetch tenemos lo siguiente:
try {
$connexion = new PDO(
"mysql:host=your-website.com;dbname=databasename",
"usuario",
"contraseña",
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())));
}Hacemos un intento de conexión a la base de datos con PDO donde basededatos debe ser el nombre de tu base de datos, usuario debe ser el nombre de usuario de la base de datos y contraseña debe ser la contraseña para acceder a la base de datos.
Si se consigue conectar con la base de datos, recibimos los parámetros start y limit para intentar ejecutar la consulta que toque en función de estos parámetros.
Si la consulta arroja información, retornamos al JavaScript el array de elementos que toca mostrar.
Si la consulta arroja la variable endItems en true, se finaliza la ejecución y ahora la función getItems() no ejecutará la llamada asíncrona.
El scroll infinito puede ser un muy buen recurso para tu página web si se utiliza de la manera adecuada.
En según que tipo de proyectos es indispensable o requerido pero para otros puede ser opcional.
Basándome tan solo en sus ventajas e inconvenientes creo que vale la pena implementarlo.
¿Tu qué opinas?
© 2026 . All rights reserved.
Desarrollador con amor por Komodo Website
Enrique
Publicado el 24/01/2023 20:31hola José, probé tu ejemplo y quería hacer una consulta, lo quise probar en el móvil pero no funciona el scroll infinito
Jose Aguilar
Publicado el 20/02/2023 16:27Hola, dejo tu consulta abierta por si alguien tuviera una solución. Saludos