jQuery - evento hashchange


86

Sto usando:

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

per associare una funzione all'evento di modifica hash. Questo sembra funzionare in IE8, Firefox e Chrome, ma non in Safari e presumo non nella versione precedente di IE. Per questi browser, desidero disabilitare il mio codice JavaScript che utilizza l'hash e l' hashchangeevento.

C'è un modo con jQuery che posso rilevare se il browser supporta l' hashchangeevento? Forse qualcosa con jQuery.support...


4
Evento hashchange jQuery: il plugin jQuery funziona perfettamente, anche in IE8. + è molto facile da usare :)
enloz

Risposte:


69

Puoi rilevare se il browser supporta l'evento:

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

Guarda anche:


Grazie per questo e per la rapida risposta.
Ian Herbert

19
Si noti che IE8 in esecuzione in modalità di compatibilità IE7 riporta true per "onhashchange" nella finestra, anche se l'evento non è supportato da jQuery Mobile
Vikas

37

Una risposta aggiornata qui a partire dal 2017, se qualcuno ne avesse bisogno, è che onhashchangeè ben supportata in tutti i principali browser. Vedere caniuse per i dettagli. Per usarlo con jQuery non è necessario alcun plugin:

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

Occasionalmente mi imbatto in sistemi legacy in cui vengono ancora utilizzati URL hashbang e questo è utile. Se stai creando qualcosa di nuovo e utilizzi collegamenti hash, ti consiglio vivamente di prendere in considerazione l'utilizzo dell'API pushState HTML5.


2
Funziona bene, usa window.location.hashper accedere all'hash corrente.
Daniel Dewhurst


18

Un approccio diverso al tuo problema ...

Esistono 3 modi per associare l'evento hashchange a un metodo:

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

O

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

O

<body onhashchange="doThisWhenTheHashChanges();">

Funzionano tutti con IE 9, FF 5, Safari 5 e Chrome 12 su Win 7.


8

prova il sito ufficiale di Mozilla: https://developer.mozilla.org/en/DOM/window.onhashchange

citare come segue:

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

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

window.onhashchange = locationHashChanged;

3

Ho appena riscontrato lo stesso problema (mancanza di eventi hashchange in IE7). Una soluzione alternativa adatta ai miei scopi era associare l'evento di clic dei collegamenti di modifica hash.

<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>

1
potresti usare $('a[href^="#"]')per ottenere collegamenti a hrefs che iniziano con un hash, evitando la necessità di aggiungere una classe
tobymackenzie,

2

Nota che nel caso di IE 7 e IE 9 if statment darà true per ("onhashchange" in windows) ma window.onhashchange non si attiverà mai, quindi è meglio memorizzare l'hash e controllarlo ogni 100 millisecondi, indipendentemente dal fatto che sia cambiato o meno per tutte le versioni di 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);
    }

2
Non è troppo da gestire per il browser? eseguire il polling per un cambio hash ogni 100 ms?
adardesign

5
il codice di esempio ha reso la mia IE8 allertare fino a quando ho aperto task manager e processo ucciso :)
enloz

questo perché c'è un errore di battitura, invece di "storedHash" usa "prevHash" e funzionerà. Fondamentalmente ha usato un nome di variabile diverso da come è stato dichiarato.
Nick

2

Che ne dici di usare un modo diverso invece dell'evento hash e ascoltare popstate come.

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

Questo metodo funziona bene nella maggior parte dei browser che ho provato finora.


1
Popstate è ancora più recente di hashchange. Ad esempio, non è supportato in IE <10.
Arturo Torres Sánchez



0

Usa Modernizr per il rilevamento delle funzionalità delle funzionalità. In generale, jQuery offre la possibilità di rilevare le funzionalità del browser: http://api.jquery.com/jQuery.support/ . Tuttavia, hashchange non è nell'elenco.

Il wiki di Modernizr offre un elenco di librerie per aggiungere funzionalità HTML5 ai vecchi browser. L' elenco per hashchange include un puntatore al progetto HTML5 History API , che sembra offrire le funzionalità di cui avresti bisogno se volessi emulare il comportamento nei vecchi browser.


0

Ecco la versione aggiornata di @ johnny.rodgers

La speranza aiuta qualcuno.

// 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);
}
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.