En la ventana.ubicación.hash - el Cambio?


Estoy usando Ajax y hash para la navegación.

¿Hay alguna manera de comprobar si el 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 navegación basada en #hash no funciona cuando presiono el botón atrás en el navegador (así que salto de bla#456 a bla#123).

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

Author: RPichioli, 2009-03-25

13 answers

La única manera de hacer esto realmente (y es cómo lo hace la 'reallysimplehistory'), es estableciendo un intervalo que mantenga la comprobación del hash actual, y comparándolo con lo que era antes, hacemos esto y dejamos que los suscriptores se suscriban a un evento cambiado que disparamos si el hash cambia.. no es perfecto, pero los navegadores realmente no admiten este evento de forma nativa.


Actualizar para mantener esta respuesta fresca:

Si está utilizando jQuery (que hoy debería ser algo fundamental para la mayoría) entonces una buena solución es utilizar la abstracción que jQuery le da mediante el uso de su sistema de eventos para escuchar los eventos de hashchange en el objeto de la ventana.

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

Lo bueno aquí es que puede escribir código que ni siquiera necesita preocuparse por el soporte de hashchange, sin embargo, necesita hacer algo de magia, en forma de una función de jQuery algo menos conocida jQuery special events.

Con esta característica, esencialmente puede ejecutar algún código de configuración para cualquier evento, la primera vez alguien intenta usar el evento de cualquier manera (como un enlace al evento).

En este código de configuración puede comprobar la compatibilidad nativa del navegador y si el navegador no implementa esto de forma nativa, puede configurar un solo temporizador para sondear los cambios y activar el evento jQuery.

Esto libera completamente su código de la necesidad de entender este problema de soporte, la implementación de un evento especial de este tipo es trivial (para obtener una versión simple de trabajo del 98%), pero ¿por qué hacer eso cuando alguien más ya tiene .

 596
Author: meandmycode,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2014-10-03 08:07:48

HTML5 especifica un evento hashchange . Este evento es ahora soportado por todos los navegadores modernos. Se agregó soporte en las siguientes versiones de navegador:

  • Internet Explorer 8
  • Firefox 3.6
  • Cromo 5
  • Safari 5
  • Opera 10.6
 274
Author: Miles,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2012-06-15 19:31:35

Tenga en cuenta que en el caso de Internet Explorer 7 e Internet Explorer 9 el estado if dará verdadero (para "onhashchange" en windows), pero el window.onhashchange nunca se disparará, por lo que es mejor almacenar hash y comprobarlo después de 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/

 50
Author: Khan Salahuddin,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2014-12-12 03:17:32

Hay muchos trucos para lidiar con la historia y la ventana.ubicación.hash en navegadores IE:

  • Como dijo la pregunta original, si pasas de la página a. html#b a. html#c, y luego presionas el botón atrás, el navegador no sabe que la página ha cambiado. Permítanme decirlo con un ejemplo: ventana.ubicación.href será 'a. html # c' , no importa si estás en a. html#b o a. html#c.

  • En realidad, a. html#b y a. html#c se almacenan en el historial solo si los elementos ' 'and' ' exists previously in the page.

  • Sin embargo, si coloca un iframe dentro de una página, navegue desde un.html#b a un.html#c en ese iframe y luego presione el botón atrás, iframe.contentWindow.documento.ubicación.href changes as expected.

  • Si utiliza ' documento.domain = algo' en tu código, entonces no puedes acceder a iframe.contentWindow.documento.open ()' (y muchos Gestores de Historial lo hacen)

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

 13
Author: Sergio Cinos,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2009-10-30 00:19:09

Firefox ha tenido un evento onhashchange desde la versión 3.6. Véase ventana.onhashchange.

 12
Author: edfuh,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2011-08-06 17:03:55

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

Si no está utilizando jQuery puede ser una referencia interesante para diseccionar.

 11
Author: CJ.,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2010-10-19 17:46:29

Podría implementar fácilmente un observador (el método "watch") en la propiedad "hash" de "window.ubicación " objeto.

Firefox tiene su propia implementación para ver los cambios de objeto, pero si usa alguna otra implementación (como Observe los cambios en las propiedades de los objetos en JavaScript) - para otros navegadores, 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 que será activa tu función de observador.

 9
Author: gion_13,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-05-23 11:47:20

Una implementación decente se puede encontrar en http://code.google.com/p/reallysimplehistory / . El único (pero también) problema y error que tiene es: en Internet Explorer modificar el hash de ubicación manualmente restablecerá toda la pila de historial (este es un problema del navegador y no se puede resolver).

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

 6
Author: Sergey Ilinsky,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2011-08-06 16:59:38

Estaba usando esto en una aplicación react para hacer que la URL mostrara diferentes parámetros dependiendo de la vista en la que estuviera el usuario.

Observé 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ó un placer, funciona con los botones del navegador hacia adelante y hacia atrás y también en el historial del navegador.

 3
Author: Sprose,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-12-07 14:36:04

Otra gran implementación es jQuery History que usará el evento nativo onhashchange si es soportado por el navegador, si no usará un iframe o intervalo apropiadamente para el navegador para asegurar que toda la funcionalidad esperada sea emulada con éxito. También proporciona una interfaz agradable para enlazar a ciertos estados.

Otro proyecto que vale la pena señalar también es jQuery Ajaxy que es más o menos una extensión para el historial de jQuery para agregar ajax a la mezcla. Como cuando comienzas a usar ajax con hashes, se vuelve bastante complicado !

 1
Author: balupton,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-05-23 12:10:40
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 presione los botones atrás o adelante, la página se recargará según el nuevo valor hash.

 1
Author: batman,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2014-04-10 10:50:03

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

Camino.js NPM

Camino.js GitHub

 1
Author: Tom,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-01-02 22:23:11

Usé un plugin de jQuery, HUtil, y escribí un YUI Historia como interfaz en la parte superior de la misma.

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

 0
Author: moha297,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2011-08-06 17:02:27