jQuery - Hashchange-Ereignis

86

Ich benutze:

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

um eine Funktion an das Hash-Änderungsereignis zu binden. Dies scheint in IE8, Firefox und Chrome zu funktionieren, aber nicht in Safari, und ich gehe davon aus, dass dies nicht in früheren Versionen von IE der Fall ist. Für diese Browser möchte ich meinen JavaScript-Code deaktivieren, der den Hash und das hashchangeEreignis verwendet.

Gibt es eine Möglichkeit mit jQuery, die ich erkennen kann, ob der Browser das hashchangeEreignis unterstützt ? Vielleicht etwas mit jQuery.support...

Ian Herbert
quelle
4
jQuery-Hashchange-Ereignis - Das jQuery-Plugin funktioniert auch in IE8 einwandfrei. + es ist sehr einfach zu bedienen :)
enloz

Antworten:

69

Sie können feststellen, ob der Browser das Ereignis unterstützt, indem Sie:

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

Siehe auch:

Christian C. Salvadó
quelle
Danke dafür und für die schnelle Antwort.
Ian Herbert
19
Beachten Sie, dass IE8, das im IE7-Kompatibilitätsmodus ausgeführt wird, für 'onhashchange' im Fenster "true" meldet, obwohl das Ereignis nicht unterstützt wird - von jQuery Mobile
Vikas
35

Eine aktualisierte Antwort hier ab 2017, falls jemand sie benötigt, ist, dass onhashchangesie in allen gängigen Browsern gut unterstützt wird. Siehe caniuse für Details. Um es mit jQuery zu verwenden, wird kein Plugin benötigt:

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

Gelegentlich stoße ich auf Legacy-Systeme, in denen noch Hashbang-URLs verwendet werden, und dies ist hilfreich. Wenn Sie etwas Neues erstellen und Hash-Links verwenden, empfehlen wir Ihnen dringend, stattdessen die HTML5-PushState-API zu verwenden.

Kevin Leary
quelle
2
Dies funktioniert gut, verwenden Sie, window.location.hashum auf den aktuellen Hash zuzugreifen.
Daniel Dewhurst
18

Es gibt ein Hashchange-Plug-In, das die hier verfügbaren Funktionen und browserübergreifenden Probleme zusammenfasst .

James Westgate
quelle
Nur erforderlich für <IE8
James Westgate
18

Eine andere Herangehensweise an Ihr Problem ...

Es gibt drei Möglichkeiten, das Hashchange-Ereignis an eine Methode zu binden:

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

Oder

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

Oder

<body onhashchange="doThisWhenTheHashChanges();">

Diese funktionieren alle mit IE 9, FF 5, Safari 5 und Chrome 12 unter Win 7.

james.garriss
quelle
8

Probieren Sie die offizielle Mozilla-Website aus: https://developer.mozilla.org/en/DOM/window.onhashchange

zitiere wie folgt:

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

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

window.onhashchange = locationHashChanged;
Paul Lan
quelle
3

Ich bin gerade auf das gleiche Problem gestoßen (fehlendes Hashchange-Ereignis in IE7). Eine für meine Zwecke geeignete Problemumgehung bestand darin, das Klickereignis der Hash-ändernden Links zu binden.

<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
quelle
1
Sie könnten verwenden $('a[href^="#"]'), um Links zu hrefs zu erhalten, die mit einem Hash beginnen, ohne die Notwendigkeit eines Klassenzusatzes zu vermeiden
tobymackenzie
2

Beachten Sie, dass im Fall von IE 7 und IE 9 die Angabe true für ("onhashchange" in Windows) ergibt, window.onhashchange jedoch niemals ausgelöst wird. Daher ist es besser, Hash zu speichern und alle 100 Millisekunden zu überprüfen, ob es geändert wurde oder nicht für alle Versionen von 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
quelle
2
Ist das nicht zu viel für den Browser? alle 100 ms nach einem Hash-Wechsel fragen?
Adardesign
5
Ihr Beispielcode hat meinen IE8 alarmiert, bis ich den Task-Manager geöffnet und den Prozess beendet habe :)
enloz
Das liegt daran, dass es einen Tippfehler gibt. Verwenden Sie anstelle von "savedHash" "prevHash" und es wird funktionieren. Er verwendete grundsätzlich einen anderen Variablennamen als deklariert.
Nick
2

Was ist mit einer anderen Methode anstelle des Hash-Ereignisses und hören Sie Popstate wie.

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

Diese Methode funktioniert gut in den meisten Browsern, die ich bisher ausprobiert habe.

Sven van den Boogaart
quelle
1
Popstate ist noch neuer als Hashchange. Zum Beispiel wird es in IE <10 nicht unterstützt.
Arturo Torres Sánchez
0

Ich denke, Chris Coyier hat eine Lösung für dieses Hashing-Problem. Schauen Sie sich seinen Screencast an:

Best Practices mit dynamischen Inhalten

Sarfraz
quelle
Danke, ich werde das untersuchen.
Ian Herbert
0

Verwenden Sie Modernizr zur Erkennung von Funktionsfunktionen. Im Allgemeinen bietet jQuery die Erkennung von Browserfunktionen an: http://api.jquery.com/jQuery.support/ . Hashchange ist jedoch nicht auf der Liste.

Das Wiki von Modernizr bietet eine Liste von Bibliotheken, mit denen Sie alten Browsern HTML5-Funktionen hinzufügen können. Die Liste für Hashchange enthält einen Zeiger auf die HTML5- Verlaufs- API des Projekts , die anscheinend die Funktionalität bietet, die Sie benötigen würden, wenn Sie das Verhalten in alten Browsern emulieren möchten.

koppor
quelle
0

Hier ist die aktualisierte Version von @ johnny.rodgers

Hoffnung hilft jemandem.

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