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
length
retorna o número de entradas no histórico de navegação:console.log("No histórico há", history.length, " registros");
A propriedade
state
retorna 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 anterior
O 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ágina
O 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 atual
O 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 eventopopstate
quando 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