On – window.location.hash – Alterar?

Estou usando o Ajax e o hash para navegação.

Existe uma maneira de verificar se o window.location.hash mudou assim?

http://example.com/blah # 123 para http://example.com/blah # 456

Funciona se eu verificar quando o documento é carregado.

Mas se eu tenho uma navegação baseada em #hash, não funciona quando eu pressiono o botão de retorno no navegador (então eu pulo do blah # 456 para o blah # 123).

Ele mostra dentro da checkbox de endereço, mas não consigo pegá-lo com JavaScript.

A única maneira de realmente fazer isso (e é como o ‘realsimplehistory’ faz isso) é definir um intervalo que continue verificando o hash atual e comparando-o com o que era antes, fazemos isso e permitimos que os assinantes se inscrevam em um evento que triggersmos se o hash mudar … não é perfeito, mas os navegadores realmente não suportam esse evento nativamente.


Atualize para manter esta resposta atualizada:

Se você estiver usando o jQuery (que hoje deve ser um pouco básico para a maioria), então uma boa solução é usar a abstração que o jQuery oferece usando seu sistema de events para escutar os events de troca no object da janela.

 $(window).on('hashchange', function() { //.. work .. }); 

O bom aqui é que você pode escrever código que não precisa nem se preocupar com suporte a hashchange, no entanto você precisa fazer alguma mágica, na forma de um evento jQuery um pouco menos conhecido jQuery events especiais .

Com esse recurso, você basicamente executa um código de configuração para qualquer evento, a primeira vez que alguém tenta usar o evento de alguma forma (como a binding ao evento).

Nesse código de configuração, você pode verificar o suporte nativo a navegadores e, se o navegador não implementar isso nativamente, você pode configurar um único timer para pesquisar alterações e triggersr o evento jQuery.

Isto desvincula completamente o seu código da necessidade de entender este problema de suporte, a implementação de um evento especial deste tipo é trivial (para obter uma versão de trabalho simples de 98%), mas por que fazer isso quando alguém já o fez .

HTML5 especifica um evento hashchange . Este evento agora é suportado por todos os navegadores modernos . Suporte foi adicionado nas seguintes versões do navegador:

  • Internet Explorer 8
  • Firefox 3.6
  • Chrome 5
  • Safari 5
  • Ópera 10.6

Observe que, no caso do Internet Explorer 7 e do Internet Explorer 9, a instrução if fornecerá a verdade (para “onhashchange” nas janelas), mas o window.onhashchange nunca será triggersdo, por isso é melhor armazenar o hash e verificá-lo a cada 100 milissegundos ele foi alterado ou não para todas as versões do Internet Explorer.

  if (("onhashchange" in window) && !($.browser.msie)) { window.onhashchange = function () { alert(window.location.hash); } // Or $(window).bind( 'hashchange',function(e) { // alert(window.location.hash); // }); } else { var prevHash = window.location.hash; window.setInterval(function () { if (window.location.hash != prevHash) { prevHash = window.location.hash; alert(window.location.hash); } }, 100); } 

EDIT – Desde o jQuery 1.9, $.browser.msie não é suportado. Fonte: http://api.jquery.com/jquery.browser/

Existem muitos truques para lidar com o History e o window.location.hash nos navegadores IE:

  • Como pergunta original, se você for da página a.html # b para a.html # c, e apertar o botão de retorno, o navegador não sabe que a página foi alterada. Deixe-me dizê-lo com um exemplo: window.location.href será ‘a.html # c’, não importa se você está em a.html # b ou a.html # c.

  • Na verdade, a.html # b e a.html # c são armazenados no histórico apenas se os elementos ‘‘ e ‘‘ existirem anteriormente na página.

  • No entanto, se você colocar um iframe em uma página, navegue de a.html # b para a.html # c nesse iframe e, em seguida, pressione o botão de retorno, iframe.contentWindow.document.location.href muda conforme o esperado.

  • Se você usa ‘document.domain = something ‘ no seu código, então você não pode acessar iframe.contentWindow.document.open () ‘(e muitos gerentes de histórico fazem isso)

Eu sei que isso não é uma resposta real, mas talvez as notas do IE-History sejam úteis para alguém.

O Firefox teve um evento onhashchange desde a 3.6. Veja window.onhashchange .

Ben Alman tem um ótimo plugin jQuery para lidar com isso: http://benalman.com/projects/jquery-hashchange-plugin/

Se você não estiver usando o jQuery, pode ser uma referência interessante para dissecar.

Você pode facilmente implementar um observador (o método “watch”) na propriedade “hash” do object “window.location”.

O Firefox tem sua própria implementação para observar mudanças de object , mas se você usar alguma outra implementação (como Watch para mudanças de propriedades de objects em JavaScript ) – para outros navegadores, isso fará o truque.

O código ficará assim:

 window.location.watch( 'hash', function(id,oldVal,newVal){ console.log("the window's hash value has changed from "+oldval+" to "+newVal); } ); 

Então você pode testá-lo:

 var myHashLink = "home"; window.location = window.location + "#" + myHashLink; 

E, claro, isso acionará sua function de observador.

Uma implementação decente pode ser encontrada em http://code.google.com/p/reallysimplehistory/ . O único (mas também) problema e bug que tem é: no Internet Explorer, modificar o hash de localização manualmente irá redefinir toda a pilha do histórico (isso é um problema do navegador e não pode ser resolvido).

Observe que o Internet Explorer 8 tem suporte para o evento “hashchange” e, como está se tornando parte do HTML5, talvez você espere que outros navegadores o acompanhem.

Eu estava usando isso em um aplicativo de resposta para fazer com que o URL exibisse parâmetros diferentes dependendo da visualização em que o usuário estava.

Eu assisti o parâmetro hash usando

 window.addEventListener('hashchange', doSomethingWithChangeFunction()); 

Então

 doSomethingWithChangeFunction () { // Get new hash value let urlParam = window.location.hash; // Do something with new hash value }; 

Trabalhou um tratamento, trabalha com botões do navegador para frente e para trás e também no histórico do navegador.

Outra grande implementação é o Histórico do jQuery, que usará o evento nativo onhashchange se ele for suportado pelo navegador. Caso contrário, ele usará um iframe ou intervalo apropriado para o navegador para garantir que toda a funcionalidade esperada seja emulada com êxito. Ele também fornece uma interface agradável para ligar a determinados estados.

Outro projeto que vale a pena notar também é o jQuery Ajaxy, que é praticamente uma extensão do histórico do jQuery para adicionar o ajax ao mix. Como quando você começa a usar ajax com hashes, isso é bastante complicado !

 var page_url = 'http://www.yoursite.com/'; // full path leading up to hash; var current_url_w_hash = page_url + window.location.hash; // now you might have something like: http://www.yoursite.com/#123 function TrackHash() { if (document.location != page_url + current_url_w_hash) { window.location = document.location; } return false; } var RunTabs = setInterval(TrackHash, 200); 

É isso … agora, sempre que você apertar os botões de voltar ou avançar, a página será recarregada de acordo com o novo valor de hash.

Eu tenho usado o path.js para o meu roteamento no lado do cliente. Eu acho que é bastante sucinto e leve (também foi publicado no NPM também), e faz uso de navegação baseada em hash.

path.js NPM

path.js GitHub

Eu usei um plugin jQuery, HUtil , e escrevi uma interface como YUI History no topo.

Confira uma vez. Se precisar de ajuda, posso ajudar.