Mudando a barra de endereço do browser sem refresh

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 post é 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. Neste post vamos falar especificamente sobre o window.history.

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 post, vou falar somente somente os 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. O evento onPopState é 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 esta entrada tenha.
URL: É a URL que você quer que a página tenha. Você pode utilizar este parametro de duas formas:

  1. Absoluta: Passando toda a nova URL completa, incluindo protocolo, host, path etc. Ex: http://blog.igorescobar.com/
  2. 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 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 entre os dois métodos é 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-nova-url');

Evento onPopState

O evento onpopstate é invocado sempre que uma nova entrada é dada no histórico de sessão do seu browser. A forma como você pode utiliza-lo é só adaptar à sua necessidade de negócio. Uma forma de utilização 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 do 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.

 

Posts Relacionados: