jQuery - événement hashchange

86

J'utilise:

$(window).bind( 'hashchange', function(e) { });

pour lier une fonction à l'événement de changement de hachage. Cela semble fonctionner dans IE8, Firefox et Chrome, mais pas dans Safari et je suppose que pas dans la version antérieure d'IE. Pour ces navigateurs, je souhaite désactiver mon code JavaScript qui utilise le hachage et l' hashchangeévénement.

Existe-t-il un moyen avec jQuery que je puisse détecter si le navigateur prend en charge l' hashchangeévénement? Peut-être quelque chose avec jQuery.support...

Ian Herbert
la source
4
Événement jQuery hashchange - le plugin jQuery fonctionne parfaitement, même dans IE8. + c'est très simple à utiliser :)
enloz

Réponses:

69

Vous pouvez détecter si le navigateur prend en charge l'événement en:

if ("onhashchange" in window) {
  //...
}

Voir également:

Christian C. Salvadó
la source
Merci pour cela et pour la réponse rapide.
Ian Herbert
19
Notez que IE8 fonctionnant en mode de compatibilité IE7 rapporte vrai pour 'onhashchange' dans la fenêtre, même si l'événement n'est pas pris en charge -de jQuery Mobile
Vikas
35

Une réponse mise à jour ici à partir de 2017, si quelqu'un en a besoin, est qu'elle onhashchangeest bien prise en charge dans tous les principaux navigateurs. Voir caniuse pour plus de détails. Pour l'utiliser avec jQuery, aucun plugin n'est nécessaire:

$( window ).on( 'hashchange', function( e ) {
    console.log( 'hash changed' );
} );

Parfois, je rencontre des systèmes hérités où les URL de hachage sont encore utilisées et cela est utile. Si vous créez quelque chose de nouveau et utilisez des liens de hachage, je vous suggère fortement d'utiliser plutôt l'API HTML5 pushState.

Kevin Leary
la source
2
Cela fonctionne bien, utilisez window.location.hashpour accéder au hachage actuel.
Daniel Dewhurst
18

Il existe un plug-in de changement de hachage qui résume les fonctionnalités et les problèmes entre navigateurs disponibles ici .

James Westgate
la source
Uniquement requis pour <IE8
James Westgate
18

Une approche différente de votre problème ...

Il existe 3 façons de lier l'événement hashchange à une méthode:

<script>
    window.onhashchange = doThisWhenTheHashChanges;
</script>

Ou

<script>
    window.addEventListener("hashchange", doThisWhenTheHashChanges, false);
</script>

Ou

<body onhashchange="doThisWhenTheHashChanges();">

Ceux-ci fonctionnent tous avec IE 9, FF 5, Safari 5 et Chrome 12 sur Win 7.

james.garriss
la source
8

essayez le site officiel de Mozilla: https://developer.mozilla.org/en/DOM/window.onhashchange

citer comme suit:

if ("onhashchange" in window) {
    alert("The browser supports the hashchange event!");
}

function locationHashChanged() {
    if (location.hash === "#somecoolfeature") {
        somecoolfeature();
    }
}

window.onhashchange = locationHashChanged;
Paul Lan
la source
3

Je viens de rencontrer le même problème (absence d'événement de changement de hachage dans IE7). Une solution de contournement qui convenait à mes besoins était de lier l'événement de clic des liens de changement de hachage.

<a class='hash-changer' href='#foo'>Foo</a>

<script type='text/javascript'>

if (("onhashchange" in window) && !($.browser.msie)) { 

    //modern browsers 
    $(window).bind('hashchange', function() {
        var hash = window.location.hash.replace(/^#/,'');
        //do whatever you need with the hash
    });

} else {

    //IE and browsers that don't support hashchange
    $('a.hash-changer').bind('click', function() {
        var hash = $(this).attr('href').replace(/^#/,'');
        //do whatever you need with the hash
    });

}

</script>
johnny.rodgers
la source
1
vous pouvez utiliser $('a[href^="#"]')pour obtenir des liens vers hrefs commençant par un hachage, évitant ainsi le besoin d'un ajout de classe
tobymackenzie
2

Notez que dans le cas de IE 7 et IE 9, si la déclaration donnera vrai pour ("onhashchange" dans Windows) mais que window.onhashchange ne se déclenchera jamais, il est donc préférable de stocker le hachage et de le vérifier toutes les 100 millisecondes s'il a changé ou non pour toutes les versions d'IE.

    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);
    }
Khan Salahuddin
la source
2
N'est-ce pas trop difficile à gérer pour le navigateur? interroger un changement de hachage toutes les 100 ms?
adardesign le
5
votre exemple de code a rendu mon alerte IE8 jusqu'à ce que
j'ouvre le
c'est parce qu'il y a une faute de frappe, au lieu de "storedHash", utilisez "prevHash" et cela fonctionnera. Il a essentiellement utilisé un nom de variable différent de la façon dont il a été déclaré.
Nick le
2

Pourquoi ne pas utiliser une manière différente au lieu de l'événement de hachage et écouter popstate comme.

window.addEventListener('popstate', function(event)
{
    if(window.location.hash) {
            var hash = window.location.hash;
            console.log(hash);
    }
});

Cette méthode fonctionne bien dans la plupart des navigateurs que j'ai essayés jusqu'à présent.

Sven van den Boogaart
la source
1
Popstate est encore plus récent que hashchange. Par exemple, il n'est pas pris en charge dans IE <10.
Arturo Torres Sánchez
0

Utilisez Modernizr pour détecter les fonctionnalités des fonctionnalités. En général, jQuery propose de détecter les fonctionnalités du navigateur: http://api.jquery.com/jQuery.support/ . Cependant, hashchange ne figure pas dans la liste.

Le wiki de Modernizr propose une liste de bibliothèques pour ajouter des capacités HTML5 aux anciens navigateurs. La liste de hashchange comprend un pointeur vers l' API HTML5 History du projet , qui semble offrir la fonctionnalité dont vous auriez besoin si vous vouliez émuler le comportement des anciens navigateurs.

Koppor
la source
0

Voici la version mise à jour de @ johnny.rodgers

L'espoir aide quelqu'un.

// ie9 ve ie7 return true but never fire, lets remove ie less then 10
if(("onhashchange" in window) && navigator.userAgent.toLowerCase().indexOf('msie') == -1){ // event supported?
    window.onhashchange = function(){
        var url = window.location.hash.substring(1);
        alert(url);
    }
}
else{ // event not supported:
    var storedhash = window.location.hash;
    window.setInterval(function(){
        if(window.location.hash != storedhash){
            storedhash = window.location.hash;
            alert(url);
        }
    }, 100);
}
Deniz Porsuk
la source