Histórico do Navegador e History API em JavaScript
Quando navegamos entre páginas, o navegador armazena todo o histórico de transições em uma pilha especial chamada history stack. A cada vez que uma nova página web é carregada ou um link é seguido, o navegador, por padrão, cria um novo registro no histórico de navegação. No JavaScript, podemos acessar o histórico através da propriedade history do objeto window. Essa propriedade representa um objeto do tipo History.
O objeto History fornece vários métodos e propriedades para interagir com o histórico de navegação:
A propriedade
lengthretorna o número de entradas no histórico de navegação:console.log("No histórico há", history.length, " registros");A propriedade
stateretorna a entrada atual do histórico de navegação. Por padrão, ao carregar a primeira página no navegador, essa propriedade énull:console.log(history.state);O método
back()retorna à entrada anterior no histórico de navegação, similar ao pressionamento do botão Voltar/Back no navegador:history.back(); // retorna à página anteriorO método
forward()avança para a próxima página visitada, similar ao pressionamento do botão Avançar/Next no navegador:history.forward(); // avança para a próxima páginaO método
go()permite navegar para frente e para trás no histórico por um número específico de páginas. O valor passado ao método define quantas páginas mover a partir da página atual. Por exemplo, um valor de -1 abre a página anterior, enquanto um valor de 1 abre a próxima página. Se um valor é passado para o qual não há uma página correspondente no histórico, esse método não faz nada. Se o método é chamado sem valor ou com valor 0, a página atual é recarregada:history.go(-2); // volta duas páginas history.go(2); // avança duas páginas history.go(0); // recarrega a página atualO método
pushState()adiciona programaticamente uma nova entrada ao histórico de navegação. Ele aceita três parâmetros:history.pushState(state, title[, url])stateé um objeto que representa o estado da página. Esse objeto é passado para o eventopopstatequando a página é acessada através do histórico de navegação.titleé o título da página. Atualmente, a maioria dos navegadores ignora esse parâmetro.urlé o URL da página. Esse parâmetro é opcional e, se não for fornecido, a página atual é recarregada.const state = { url: "/", title: "Home", decription: "Home Page" }; history.pushState(state, state.title, state.url); // com url
O método
replaceState()substitui programaticamente a entrada atual no histórico por uma nova. Ele também aceita três parâmetros:history.replaceState(state, title, [url]);Um exemplo:
const state = { url: "home", title: "Home", decription: "Home Page" }; history.replaceState(state, state.title, state.url);
O Evento popstate
O evento popstate é acionado sempre que a entrada atual no histórico de navegação é alterada, por exemplo, ao pressionar o botão "Voltar" no navegador. Para manipular mudanças no histórico de navegação com os botões Voltar/Avançar do navegador, este evento deve ser tratado.
window.addEventListener("popstate", (event) => {
// obtém o estado anterior
console.log(event.state);
});Navegação em um Site de Página Única
A manipulação do histórico de navegação é especialmente útil em sites de página única (SPA). Em um SPA, o conteúdo é carregado dinamicamente sem recarregar a página. Isso significa que o histórico de navegação não é atualizado automaticamente.
Exemplo:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title>Programício</title>
</head>
<body>
<nav><a href="#home">Home</a> | <a href="#about">About</a> | <a href="#contacts">Contacts</a></nav>
<h1 id="content"></h1>
<script>
// Container onde o conteúdo é carregado
const contentElement = document.getElementById("content");
// Objeto contendo o conteúdo para diferentes páginas
const pages = {
home: { content: "Página Inicial", url: "#home" },
about: { content: "Sobre", url: "#about" },
contacts: { content: "Contato", url: "#contacts" },
};
// Manipulador para cliques nos links
function handleClick(event) {
const url = event.target.getAttribute("href");
const pageName = url.split("#").pop();
const page = pages[pageName];
if (history.state.url != url) {
contentElement.textContent = page.content;
history.pushState(page, event.target.textContent, event.target.href);
document.title = event.target.textContent;
}
return event.preventDefault();
}
window.addEventListener("popstate", (event) => {
if (event.state) contentElement.textContent = event.state.content;
});
const links = document.getElementsByTagName("a");
for (let i = 0; i < links.length; i++) {
links[i].addEventListener("click", handleClick, true);
}
contentElement.textContent = pages.home.content;
history.pushState(pages.home, "Home", pages.home.url);
</script>
</body>
</html>O exemplo acima mostra como o API de Histórico pode ser usado para criar uma experiência de navegação eficiente e intuitiva em um site de página única, onde o conteúdo é carregado dinamicamente sem a necessidade de recarregar a página. Isso é particularmente útil em aplicações da web modernos, onde a velocidade e a fluidez da experiência do usuário são cruciais.
Além disso, ao invés de usar o caractere de hash # para identificar links, você pode optar por usar barras /, o que pode ser melhor para a indexação de páginas por motores de busca (SEO).
Porém, o uso de barras exige que a página seja hospedada em um servidor web