A funcionalidade de rolagem infinita proporciona um carregamento contínuo de conteúdo à medida que o utilizador desliza pela página, diferindo do método tradicional de paginação, que exige cliques para carregar. Este recurso pode aprimorar significativamente a experiência do utilizador, especialmente em dispositivos móveis, oferecendo uma navegação mais fluida.
Neste guia, exploraremos como implementar a rolagem infinita utilizando HTML, CSS e JavaScript de forma simples e eficaz.
Configuração do Front-end
Para começar, é necessário estruturar o HTML básico para exibir o conteúdo. O exemplo abaixo ilustra essa estrutura inicial:
<link rel="stylesheet" href="https://wilku.top/how-to-implement-infinite-scroll-in-a-web-application/style.css" /> <h1>Página de Rolagem Infinita</h1> <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> <script src="https://wilku.top/how-to-implement-infinite-scroll-in-a-web-application/script.js"></script>
Nesta estrutura, apresentamos uma série de imagens temporárias e referenciamos dois arquivos externos: um arquivo CSS para estilização e um arquivo JavaScript para lógica.
Estilização CSS para Conteúdo Rolável
Para organizar as imagens temporárias em formato de grade, aplique o seguinte CSS no arquivo `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%); }
Com estas regras CSS, a sua página deverá apresentar um layout similar ao seguinte:
Implementação Essencial com JavaScript
O próximo passo é editar o arquivo `script.js`. Para implementar a rolagem infinita, é fundamental identificar quando o utilizador se aproxima do final do contêiner de conteúdo ou da página.
"use strict"; window.addEventListener("scroll", () => { if ( window.scrollY + window.innerHeight >= document.documentElement.scrollHeight - 100 ) { fetchMoreContent(); } });
A função `fetchMoreContent` tem como objetivo carregar mais dados temporários.
async function fetchMoreContent() { try { let response = await fetch("https://fakestoreapi.com/products?limit=3"); if (!response.ok) { throw new Error("A resposta da rede não foi bem-sucedida."); } let data = await response.json(); console.log(data); } catch (error) { console.error("Houve um problema ao buscar o novo conteúdo:", error); } finally { console.log("A função de busca foi disparada"); } }
Para este projeto, utilizamos a API fakestoreapi.
Para verificar se os dados estão sendo buscados corretamente ao rolar, consulte o console do navegador:
Observará que os dados são buscados repetidamente ao rolar, o que pode impactar o desempenho do dispositivo. Para otimizar, vamos criar um estado inicial para controlar a busca de dados:
let isFetching = false;
Agora, modificaremos a função `fetchMoreContent` para que ela só busque dados após a conclusão da busca anterior:
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("A resposta da rede não foi bem-sucedida."); } let data = await response.json(); } catch (error) { console.error("Houve um problema ao buscar o novo conteúdo:", error); } finally { console.log("A função de busca foi disparada"); isFetching = false; } }
Apresentando o Novo Conteúdo
Para exibir novos elementos quando o utilizador rola a página, criaremos uma função para anexar as imagens ao contêiner principal.
Inicialmente, vamos selecionar o elemento principal:
const productsList = document.querySelector(".products__list");
Em seguida, definimos uma função para adicionar o conteúdo:
function displayNewContent(data) { data.forEach((item) => { const imgElement = document.createElement("img"); imgElement.src = item.image; imgElement.alt = item.title; productsList.appendChild(imgElement); }); }
Finalmente, modificamos a função `fetchMoreContent` para passar os dados buscados para a função de acréscimo:
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("A resposta da rede não foi bem-sucedida."); } let data = await response.json(); displayNewContent(data); } catch (error) { console.error("Houve um problema ao buscar o novo conteúdo:", error); } finally { console.log("A função de busca foi disparada"); isFetching = false; } }
Com essas alterações, a rolagem infinita está funcional.
Para melhorar a experiência do utilizador, vamos apresentar um indicador de carregamento enquanto o novo conteúdo é buscado. Inicialmente, adicione este HTML:
<h1 class="loading-indicator">Carregando...</h1>
Em seguida, selecionamos o elemento de carregamento:
const loadingIndicator = document.querySelector(".loading-indicator");
E criamos duas funções para controlar a visibilidade do indicador de carregamento:
function showLoadingIndicator() { loadingIndicator.style.display = "block"; console.log("Carregando..."); } function hideLoadingIndicator() { loadingIndicator.style.display = "none"; console.log("Carregamento concluído."); }
Agora, adicionamos essas funções à função de busca:
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("A resposta da rede não foi bem-sucedida."); } let data = await response.json(); displayNewContent(data); } catch (error) { console.error("Houve um problema ao buscar o novo conteúdo:", error); } finally { console.log("A função de busca foi disparada"); hideLoadingIndicator(); isFetching = false; } }
O resultado destas modificações proporciona uma melhor experiência ao utilizador.
Algumas práticas recomendadas a considerar incluem:
- Evitar buscar muitos itens simultaneamente, pois isso pode sobrecarregar o navegador e prejudicar o desempenho.
- Utilizar uma função de “debounce” para atrasar ligeiramente a busca de conteúdo após detetar um evento de rolagem. Esta prática pode evitar o excesso de solicitações à rede.
- Oferecer uma alternativa para a paginação tradicional, dado que nem todos os utilizadores preferem a rolagem infinita.
- Informar o utilizador quando não houver mais conteúdo a ser carregado, em vez de tentar buscar continuamente.
Aperfeiçoando o Carregamento Contínuo de Conteúdo
A rolagem infinita aprimora a navegação contínua, especialmente em dispositivos móveis. Ao aplicar as técnicas e dicas apresentadas, você poderá incorporar este recurso nos seus sites.
É fundamental prestar atenção à experiência do utilizador, incluindo a apresentação de indicadores de progresso e mensagens de erro, para assegurar uma navegação intuitiva e eficaz.