Manejar el evento de cambio de anclaje de URL en js

Respuestas:

126

Los motores de búsqueda personalizados de Google usan un temporizador para comparar el hash con un valor anterior, mientras que el iframe secundario en un dominio separado actualiza el hash de la ubicación principal para contener el tamaño del cuerpo del documento iframe. Cuando el temporizador detecta el cambio, el padre puede cambiar el tamaño del iframe para que coincida con el del cuerpo de modo que no se muestren las barras de desplazamiento.

Algo como lo siguiente logra lo mismo:

var storedHash = window.location.hash;
window.setInterval(function () {
    if (window.location.hash != storedHash) {
        storedHash = window.location.hash;
        hashChanged(storedHash);
    }
}, 100); // Google uses 100ms intervals I think, might be lower

Google Chrome 5, Safari 5, Opera 10.60 , Firefox 3.6 y Internet Explorer 8 todo el apoyo del hashchangeevento:

if ("onhashchange" in window) // does the browser support the hashchange event?
    window.onhashchange = function () {
        hashChanged(window.location.hash);
    }

y poniéndolo junto:

if ("onhashchange" in window) { // event supported?
    window.onhashchange = function () {
        hashChanged(window.location.hash);
    }
}
else { // event not supported:
    var storedHash = window.location.hash;
    window.setInterval(function () {
        if (window.location.hash != storedHash) {
            storedHash = window.location.hash;
            hashChanged(storedHash);
        }
    }, 100);
}

jQuery también tiene un complemento que verificará el evento hashchange y proporcionará el suyo si es necesario: http://benalman.com/projects/jquery-hashchange-plugin/ .

EDITAR : Soporte de navegador actualizado (nuevamente).

Andy E
fuente
para completar, agregue var storedHash = window.location.hash;al bloque de resumen de armarlo. Por cierto: hoy en día esto se llama polyfill, creo.
Frank Nocke
1
Hoy en día, puede escuchar hashChangeen window stackoverflow.com/questions/6390341/how-to-detect-url-change
Timo Huovinen
@AndyE lo hice leer la respuesta, echaba de menos la nota pequeña, y nunca he visto acontecimientos que parecenhashChanged(storedHash);
Timo Huovinen
1
@TimoHuovinen:, hashChangeden este caso, se pretende que sea una función implementada por un desarrollador que utiliza este código. La respuesta aquí solo demuestra cómo se puede monitorear el hash para detectar cambios donde el onhashchangeevento no está disponible, y combina los enfoques basados ​​en eventos y basados ​​en temporizadores para proporcionar una solución universal. Mi punto es que la respuesta a la que vinculó no agrega absolutamente nada a la respuesta aquí ;-). Proporcionan la misma información básica, incluso el enlace al complemento jQuery de Ben Alman. La única diferencia es que proporcioné una solución JS pura en mi respuesta.
Andy E
1
Estaba buscando un enrutador JS liviano, pero esto funcionó muy bien. También se eliminaron todas las dependencias :)
gskema
4

Recomendaría usar en addEventListenerlugar de sobrescribir window.onhashchange, de lo contrario, bloqueará el evento para otros complementos.

window.addEventListener('hashchange', function() {
...
})

En cuanto al uso global del navegador en la actualidad, ya no se necesita un respaldo.

Fabian von Ellerts
fuente
2

Por lo que veo en otras preguntas de SO, la única solución viable entre navegadores es un temporizador. Mira esta pregunta, por ejemplo.

Pekka
fuente
1

(Solo para que conste.) El evento sintético "hashchange" YUI3 hace más o menos lo mismo que la respuesta aceptada

YUI().use('history-hash', function (Y) {
  Y.on('hashchange', function (e) {
    // Handle hashchange events on the current window.
  }, Y.config.win);
});
mjhm
fuente
0

Puede obtener más información de este

Tipos de eventos de mutación

El módulo de eventos de mutación está diseñado para permitir la notificación de cualquier cambio en la estructura de un documento, incluidas las modificaciones de attr y texto.

rahul
fuente
Se trata de cambios DOM.
Raj