web-dev-qa-db-fra.com

Sur - window.location.hash - Changer?

J'utilise Ajax et hash pour la navigation.

Est-il possible de vérifier si le window.location.hash a changé de la sorte?

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

Cela fonctionne si je le vérifie lors du chargement du document.

Mais si ma navigation est basée sur #hash, cela ne fonctionne pas lorsque j'appuie sur le bouton Précédent du navigateur (je passe donc de blah n ° 456 à blah n ° 123).

Il apparaît dans la zone d'adresse, mais je ne parviens pas à l'attraper avec JavaScript.

543
MilMike

La seule façon de vraiment faire cela (et c'est ainsi que le "vraiment simpliste" fait cela, est de définir un intervalle qui vérifie le hachage actuel, et de le comparer avec ce qu'il était auparavant, nous le faisons et nous permettons aux abonnés de s'abonner à un changement. événement que nous tirons si le hachage change .. ce n’est pas parfait mais les navigateurs ne supportent vraiment pas cet événement de manière native.


Mise à jour pour garder cette réponse fraîche:

Si vous utilisez jQuery (ce qui aujourd'hui devrait être quelque peu fondamental pour la plupart), une solution intéressante consiste à utiliser l'abstraction que jQuery vous donne en utilisant son système d'événements pour écouter les événements hashchange sur l'objet window.

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

La bonne chose ici est que vous pouvez écrire du code qui n’a même pas besoin de vous inquiéter à propos de la prise en charge de hashchange, mais vous devez faire un peu de magie, sous la forme d’une fonctionnalité jQuery un peu moins connue événements spéciaux de jQuery .

Avec cette fonctionnalité, vous devez essentiellement exécuter du code de configuration pour tout événement, la première fois que quelqu'un tente d'utiliser l'événement de quelque manière que ce soit (par exemple, une liaison à l'événement).

Dans ce code de configuration, vous pouvez vérifier la prise en charge du navigateur natif et, si le navigateur ne l'implémente pas de manière native, vous pouvez configurer un seul temporisateur pour interroger les modifications et déclencher l'événement jQuery.

Cela dissocie totalement votre code de la nécessité de comprendre ce problème de support. La mise en œuvre d'un événement spécial de ce type est triviale (obtenir une version simple à 98% de travail), mais pourquoi faire cela quand quelqu'un d'autre l'a déjà fait =.

604
meandmycode

HTML5 spécifie un événement hashchange . Cet événement est maintenant supporté par tous les navigateurs modernes . Une assistance a été ajoutée dans les versions de navigateur suivantes:

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

Notez que dans le cas d'Internet Explorer 7 et d'Internet Explorer 9, la déclaration if donnera true (pour "onhashchange" dans Windows), mais le window.onhashchange ne se déclenchera jamais. Il est donc préférable de stocker hasch et check toutes les 100 millisecondes, qu’il soit modifié ou non pour toutes les versions d’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 - Depuis jQuery 1.9, $.browser.msie n'est plus pris en charge. Source: http://api.jquery.com/jquery.browser/

50
Khan Salahuddin

Il existe de nombreuses astuces pour gérer History et window.location.hash dans les navigateurs IE:

  • Comme le disait la question initiale, si vous passez de la page a.html # b à a.html # c et que vous cliquez ensuite sur le bouton Précédent, le navigateur ne sait pas que cette page a été modifiée. Laissez-moi vous le dire avec un exemple: window.location.href sera 'a.html # c', peu importe si vous êtes dans a.html # b ou a.html # c.

  • En fait, a.html # b et a.html # c sont stockés dans l’historique niquement si les éléments '<a name="#b">' et '<a name="#c">' existe déjà dans la page.

  • Toutefois, si vous placez un iframe dans une page, naviguez de a.html # b à a.html # c dans cette iframe, puis cliquez sur le bouton Précédent. Iframe.contentWindow.document.location.href change comme prévu.

  • Si vous utilisez 'document.domain = quelque chose' dans votre code, vous ne pourrez pas accéder à iframe.contentWindow.document.open () '(et de nombreux gestionnaires de l'historique le font)

Je sais que ce n'est pas une vraie réponse, mais peut-être que les notes d'IE-History sont utiles à quelqu'un.

14
Sergio Cinos

Firefox a eu un événement onhashchange depuis la 3.6. Voir window.onhashchange.

12
edfuh

Ben Alman a un excellent plugin jQuery pour traiter ceci: http://benalman.com/projects/jquery-hashchange-plugin/

Si vous n'utilisez pas jQuery, cela peut être une référence intéressante à disséquer.

11
CJ.

Vous pouvez facilement implémenter un observateur (la méthode "watch") sur la propriété "hash" de l'objet "window.location".

Firefox a sa propre implémentation pour observer les changements d'objet , mais si vous utilisez une autre implémentation (telle que surveillez les modifications des propriétés de l'objet dans JavaScript) = ) - pour les autres navigateurs, cela fera l'affaire.

Le code ressemblera à ceci:

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

Ensuite, vous pouvez le tester:

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

Et bien sûr, cela déclenchera votre fonction d'observateur.

9
gion_13

J'utilisais cela dans une application de réaction pour faire en sorte que l'URL affiche différents paramètres en fonction de la vue de l'utilisateur.

J'ai regardé le paramètre de hachage en utilisant

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

Ensuite

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

A travaillé un festin, fonctionne avec les boutons en avant et en arrière du navigateur et aussi dans l'historique du navigateur.

6
Sprose

Une mise en œuvre décente peut être trouvée à l’adresse http://code.google.com/p/reallysimplehistory/ . Le seul problème (mais aussi) et le bogue qu’il a est celui-ci: dans Internet Explorer, modifier manuellement le hachage d’emplacement réinitialisera l’ensemble de la pile d’historique (il s’agit d’un problème de navigateur qui ne peut pas être résolu).

Remarque: Internet Explorer 8 prend en charge l'événement "hashchange" et, puisqu'il fait désormais partie de HTML5, vous pouvez vous attendre à ce que les autres navigateurs se mettent à jour.

6
Sergey Ilinsky
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);

C'est ça ... maintenant, chaque fois que vous appuyez sur vos boutons Précédent ou Suivant, la page se rechargera conformément à la nouvelle valeur de hachage.

1
batman

Une autre bonne implémentation est jQuery History qui utilisera l’événement onhashchange natif s’il est pris en charge par le navigateur, sinon il utilisera un iframe ou un intervalle approprié pour le navigateur afin de garantir l’émulation de toutes les fonctionnalités attendues. . Il fournit également une interface agréable pour se connecter à certains états.

Un autre projet à noter est jQuery Ajaxy , qui est une extension pour jQuery History d’ajouter un ajax au mélange. Comme lorsque vous commencez à utiliser ajax avec des hachages, cela devient assez compliqué !

1
balupton

J'utilise path.js pour mon routage côté client. Je l'ai trouvé assez succinct et léger (il a également été publié dans NPM également) et utilise la navigation à base de hachage.

path.js NPM

path.js GitHub

1
Tom

J'ai utilisé un plugin jQuery, HUtil , et écrit un historique YUI comme une interface semblable.

Vérifiez-le une fois. Si vous avez besoin d'aide, je peux vous aider.

0
moha297