web-dev-qa-db-fra.com

Gérer l'événement de changement d'ancrage d'URL dans js

Comment puis-je écrire le code de rappel JavaScript qui sera exécuté lors de toute modification de l'ancre URL?

Par exemple de http://example.com#a à http://example.com#b

86
Bogdan Gusiev

Les moteurs de recherche personnalisés Google utilisent une minuterie pour comparer le hachage avec une valeur précédente, tandis que l'iframe enfant sur un domaine séparé met à jour le hachage de l'emplacement du parent pour contenir la taille du corps du document iframe. Lorsque le minuteur intercepte la modification, le parent peut redimensionner l'iframe pour qu'il corresponde à celui du corps afin que les barres de défilement ne s'affichent pas.

Quelque chose comme ce qui suit obtient le même résultat:

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.6 , Firefox 3.6 et Internet Explorer 8 tous prennent en charge l'événement hashchange:

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

et le rassembler:

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 a également un plugin qui vérifiera l'événement de hachage et fournira le sien si nécessaire - http://benalman.com/projects/jquery-hashchange-plugin/ .

[~ # ~] modifier [~ # ~] : Prise en charge du navigateur mise à jour (à nouveau).

124
Andy E

setInterval() n'est pour l'instant que la solution universelle. Mais il y a de la lumière dans le futur sous forme de événement hashchange

3
NilColor

D'après ce que je vois dans d'autres SO questions, la seule solution multi-navigateur réalisable est une minuterie. Consultez cette question par exemple.

2
Pekka 웃

(Juste pour mémoire.) L'événement synthétique "hashchange" de YUI3 fait plus ou moins la même chose que la réponse acceptée

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

Je recommanderais d'utiliser addEventListener au lieu d'écraser window.onhashchange, sinon vous bloquerez l'événement pour les autres plugins.

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

En regardant l'utilisation globale du navigateur aujourd'hui, une solution de rechange n'est plus nécessaire.

1
Fabian von Ellerts

Vous pouvez en obtenir plus d'informations

types d'événements de mutation

Le module d'événement de mutation est conçu pour permettre la notification de tout changement dans la structure d'un document, y compris attr et modifications de texte.

0
rahul