Hoje vamos falar sobre um recurso bastante interessante dos nossos browsers, que nos permite fazer a alteração das informações das páginas que acessamos, inclusive a URL que é mostrada na barra de endereço do seu browser, sem fazer o uso do refresh e o melhor: mantendo o histórico.
Manipulando o histórico do browser
Para se fazer o que é proposto neste artigo, é preciso entender como funciona a manipulação do histórico do nosso browser e os métodos que o objeto DOM window nos proporciona para manipular o nosso histórico. Hoje, vamos falar especificamente sobre o window.history.
A W3C implementa History com a seguinte interface:
interface History {
readonly attribute long length;
readonly attribute any state;
void go(optional long delta);
void back();
void forward();
void pushState(any data, DOMString title, optional DOMString url);
void replaceState(any data, DOMString title, optional DOMString url);
};
Neste artigo, vou falar somente dos métodos pushState e replaceState, que são os métodos responsáveis por manipular o histórico da sessão do seu navegador.
Sempre que você abre uma nova aba e/ou janela, o navegador inicia uma nova sessão. E é nesta sessão que ele armazena todas as URL’s que você visitou.
Método history.pushState
O método pushState registra uma nova entrada no seu histórico de sessão, mantendo o histórico. E essa é a sua sintaxe:
window.history.pushState(data, title [, url ] )
- Data: O parâmetro data pode ser útil caso você queira utilizar o evento onPopState, que é invocado sempre que uma nova entrada é registrada no seu histórico de sessão;
- Title: É o título da página que você quer que a entrada tenha;
- URL: É a URL que você quer que a página tenha. Você pode utilizar este parametro de duas formas:
- Absoluta: Passando toda a nova URL completa, incluindo protocolo, host, path etc. Ex: http://blog.igorescobar.com/;
- Relativa: A URL que você passar, será relativa a URL atual, ou seja, se você estiver acessando o http://blog.igorescobar.com/ e passar “/category/javascript/” a URL que será registrada é “http://blog.igorescobar.com/category/javascript/”.
Exemplo:
window.history.pushState('Object', 'Categoria JavaScript', '/category/javascript/');
O resultado deste código vai fazer com que a URL e o título da página que você estiver navegando mude, sem que o refresh ocorra. E se você apertar o “voltar” no seu navegador, vai ver que ele vai voltar para a página anterior que você tinha acessado, ou seja, o histórico foi mantido.
Método history.replaceState
O método replaceState é muito parecido com o pushState. A única diferença é que o pushState armazena uma nova entrada, mantendo o histórico. O replaceState, não; ele substituí a entrada do histórico de sessão atual pelos dados que você passa. E essa é a sua sintaxe:
window.history.replaceState(data, title [, url ] )
Exemplo:
window.history.replaceState('Object', 'Titulo da Página', '/outra-n
Evento onPopState
O evento onpopstate é invocado sempre que uma nova entrada é dada no histórico de sessão do seu browser. Para utilizá-lo, é só adaptar à sua necessidade de negócio. Uma forma de uso deste evento é delegar para ele a responsabilidade de carregar, via ajax, todo o link que for clicado, por exemplo.
Exemplo de navegação sem refresh
Todo mundo já conhece o GitHub, certo? (espero que sim!) O GitHub faz uso deste mesmo recurso para que vocês consigam visualizar os arquivos de um repositório de maneira rápida, sem refresh e mantendo um histórico da navegação. Veja que sempre que você clica em um arquivo, ele é carregado dentro do mesmo contexto, a url da página muda e você consegue ir para frente e voltar no histórico, graças ao método window.history.pushState.
Este é um exemplo de como seria a implementação de uma navegação parecida com jQuery:
$('#menu-nav a')??.click(function(e){
e.preventDefault();
window.history.pushState({url: "" + $(this).attr('href') + ""}, $(this).attr('title') , $(this).attr('href'));
});?
$(window).bind("popstate", function(e) {
$('#my-navigation-container').load(e.state.url);
});
Compatibilidade
Os browsers Chrome, Opera, Safari e Firefox 4+ implementam todos estes métodos de forma nativa. Os browsers antigos utilizam o location.hash para imitar o comportamento. Existe uma biblioteca chamada History.js que implementa esta funcionalidade de forma crossbrowser.