En – window.location.hash – ¿Cambiar?

Estoy usando Ajax y hash para la navigation.

¿Hay alguna forma de comprobar si window.location.hash cambió así?

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

Funciona si lo compruebo cuando se carga el documento.

Pero si tengo una navigation basada en #hash, no funciona cuando presiono el button Atrás en el browser (así que salto de bla # 456 a bla # 123).

Se muestra dentro del cuadro de dirección, pero no puedo verlo con JavaScript.

La única forma de hacer esto (y así es como lo hace la'historia realmente simple ') consiste en establecer un intervalo que siga comprobando el hash actual y compararlo con lo que era antes, hacemos esto y permitimos que los suscriptores se suscriban a un cambio evento que disparamos si el hash cambia … no es perfecto, pero los browseres realmente no admiten este evento de forma nativa.


Actualice para mantener esta respuesta fresca:

Si está utilizando jQuery (que hoy debería ser un tanto fundamental para la mayoría), entonces una buena solución es usar la abstracción que jQuery le brinda al usar su sistema de events para escuchar events de intercambio en el object de la window.

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

Lo bueno de esto es que puedes escribir código que ni siquiera necesita preocuparse por el soporte de hashchange, sin embargo, debes HACER algo de magia, en forma de un evento jQuery algo less conocido, events especiales de jQuery .

Con esta function, básicamente puedes ejecutar algún código de configuration para cualquier evento, la primera vez que alguien intenta usar el evento de alguna manera (como por ejemplo vincularse al evento).

En este código de configuration puede verificar si hay compatibilidad con el browser nativo y si el browser no lo implementa de forma nativa, puede configurar un solo timer para search cambios y activar el evento jQuery.

Esto desvincula por completo su código de la necesidad de comprender este problema de soporte, la implementación de un evento especial de este tipo es trivial (para get una versión simple que funcione al 98%), pero ¿por qué hacerlo cuando alguien más ya lo hizo ?

HTML5 especifica un evento hashchange . Este evento ahora es compatible con todos los browseres modernos . Se agregó soporte en las siguientes versiones de browser:

  • Internet Explorer 8
  • Firefox 3.6
  • Chrome 5
  • Safari 5
  • Opera 10.6

Tenga en count que en caso de Internet Explorer 7 e Internet Explorer 9, la condición if dará verdadero (para "onhashchange" en Windows), pero window.onhashchange nunca se disparará, por lo que es mejor almacenar el hash y verificarlo cada 100 milisegundos si ha cambiado o no para todas las versiones de 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); } 

EDITAR: desde jQuery 1.9, $.browser.msie no es compatible. Fuente: http://api.jquery.com/jquery.browser/

Hay muchos trucos para tratar con History y window.location.hash en los browseres IE:

  • Como decía la pregunta original, si pasas de la página a.html # b a a.html # c, y luego presionas el button Atrás, el browser no sabe que la página ha cambiado. Permítanme decirlo con un ejemplo: window.location.href será 'a.html # c', sin importar si está en a.html # by a.html # c.

  • De hecho, a.html # b y a.html # c se almacenan en el historial solo si los elementos '<a name="#b">' y '<a name="#c">' existen anteriormente en la página.

  • Sin embargo, si coloca un iframe dentro de una página, navegue de a.html # b a a.html # c en ese iframe y luego presione el button Atrás, iframe.contentWindow.document.location.href cambia según lo esperado.

  • Si usa 'document.domain = something ' en su código, entonces no puede acceder a iframe.contentWindow.document.open () '(y muchos History Managers lo hacen)

Sé que esta no es una respuesta real, pero tal vez las notas de IE-History son útiles para alguien.

Firefox ha tenido un evento onhashchange desde 3.6. Ver window.onhashchange .

Ben Alman tiene un excelente plugin de jQuery para lidiar con esto: http://benalman.com/projects/jquery-hashchange-plugin/

Si no usas jQuery, puede ser una reference interesante para diseccionar.

Podría implementar fácilmente un observador (el método "mirar") en la propiedad "hash" del object "window.location".

Firefox tiene su propia implementación para ver los cambios de object , pero si usa alguna otra implementación (como Watch for object properties changes in JavaScript ) – para otros browseres, eso hará el truco.

El código se verá así:

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

Entonces puedes probarlo:

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

Y, por supuesto, eso activará su function de observador.

Se puede encontrar una implementación decente en http://code.google.com/p/reallysimplehistory/ . El único (y también) problema y error que tiene es que en Internet Explorer la modificación del hash de location manualmente restablecerá toda la stack del historial (este es un problema del browser y no se puede resolver).

Tenga en count que Internet Explorer 8 tiene soporte para el evento "hashchange" y, como se está convirtiendo en parte de HTML5, puede esperar que otros browseres se pongan al día.

Otra gran implementación es jQuery History, que usará el evento onhashchange nativo si es compatible con el browser, si no utilizará un iframe o intervalo de manera apropiada para el browser para garantizar que toda la funcionalidad esperada se emule con éxito. También proporciona una interfaz agradable para enlazar a ciertos estados.

Otro proyecto que también vale la pena destacar es jQuery Ajaxy, que es una extensión bastante para jQuery History para agregar ajax a la mezcla. ¡Como cuando comienzas a usar ajax con hashes, es 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); 

Eso es todo … ahora, cada vez que presionas los botones de atrás o adelante, la página se volverá a cargar según el nuevo valor de hash.

He estado usando path.js para mi routing del lado del cliente. He encontrado que es bastante sucinto y ligero (también se ha publicado en NPM), y hace uso de la navigation basada en hash.

path.js NPM

path.js GitHub

Usé un plugin jQuery, HUtil , y escribí una interfaz similar a YUI History encima.

Compruébalo una vez. Si necesitas ayuda, puedo ayudarte.

Estaba usando esto en una aplicación de reacción para hacer que la URL muestre diferentes parameters dependiendo de en qué vista esté el usuario.

Vi el parámetro hash usando

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

Entonces

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

Funcionó como un regalo, funciona con los botones del browser hacia adelante y hacia atrás y también en el historial del browser.