jQuery - zdarzenie hashchange

86

Ja używam:

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

aby powiązać funkcję ze zdarzeniem hash change. Wydaje się, że działa to w IE8, Firefox i Chrome, ale nie w Safari i zakładam, że nie we wcześniejszej wersji IE. W przypadku tych przeglądarek chcę wyłączyć mój kod JavaScript, który używa skrótu i hashchangezdarzenia.

Czy w jQuery jest sposób, który mogę wykryć, czy przeglądarka obsługuje hashchangezdarzenie? Może coś z jQuery.support...

Ian Herbert
źródło
4
jQuery hashchange event - wtyczka jQuery działa doskonale, nawet w IE8. + jest bardzo łatwy w użyciu :)
powiększ

Odpowiedzi:

36

Zaktualizowana odpowiedź od 2017 roku, jeśli ktoś jej potrzebuje, onhashchangejest dobrze obsługiwana we wszystkich głównych przeglądarkach. Zobacz caniuse po szczegóły. Aby używać go z jQuery, nie jest potrzebna żadna wtyczka:

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

Czasami napotykam starsze systemy, w których adresy URL z hashbang są nadal używane i jest to pomocne. Jeśli tworzysz coś nowego i używasz haszujących linków, zdecydowanie sugeruję rozważenie zamiast tego skorzystania z HTML5 pushState API.

Kevin Leary
źródło
2
Działa to dobrze, użyj, window.location.hashaby uzyskać dostęp do bieżącego skrótu.
Daniel Dewhurst,
18

Istnieje wtyczka do zmiany skrótów, która podsumowuje dostępne tutaj funkcje i problemy z różnymi przeglądarkami .

James Westgate
źródło
Wymagane tylko dla <IE8
James Westgate,
18

Inne podejście do problemu ...

Istnieją 3 sposoby powiązania zdarzenia hashchange z metodą:

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

Lub

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

Lub

<body onhashchange="doThisWhenTheHashChanges();">

Wszystkie działają z IE 9, FF 5, Safari 5 i Chrome 12 na Win 7.

james.garriss
źródło
8

wypróbuj oficjalną stronę Mozilli: https://developer.mozilla.org/en/DOM/window.onhashchange

cytuj następująco:

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

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

window.onhashchange = locationHashChanged;
Paul Lan
źródło
3

Właśnie napotkałem ten sam problem (brak zdarzenia hashchange w IE7). Obejściem, które pasowało do moich celów, było powiązanie zdarzenia kliknięcia linków zmieniających 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>
johnny.rodgers
źródło
1
możesz użyć $('a[href^="#"]')do uzyskania linków do hrefs zaczynających się od hasha, unikając potrzeby dodawania klasy
tobymackenzie
2

Zauważ, że w przypadku IE 7 i IE 9, jeśli statment da prawdę dla ("onhashchange" w oknach), ale window.onhashchange nigdy się nie uruchomi, więc lepiej jest przechowywać hash i sprawdzać go po każdych 100 milisekundach, czy został zmieniony, czy nie dla wszystkich wersji 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
źródło
2
Czy to nie za dużo dla przeglądarki? sondować pod kątem zmiany hash co 100 ms?
adardesign
5
Twój przykładowy kod sprawił, że IE8 ostrzegał mnie, dopóki nie otworzyłem menedżera zadań i nie zabiłem procesu :)
powiększ
Dzieje się tak dlatego, że jest literówka, zamiast „storeHash” użyj „prevHash” i to zadziała. Zasadniczo użył innej nazwy zmiennej niż została zadeklarowana.
Nick
2

Co powiesz na użycie innego sposobu zamiast zdarzenia skrótu i ​​słuchanie popstate.

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

Ta metoda działa dobrze w większości przeglądarek, które do tej pory wypróbowałem.

Sven van den Boogaart
źródło
1
Popstate jest jeszcze nowszy niż hashchange. Na przykład nie jest obsługiwany w IE <10.
Arturo Torres Sánchez
0

Użyj Modernizr do wykrywania możliwości funkcji. Ogólnie jQuery oferuje wykrywanie funkcji przeglądarki: http://api.jquery.com/jQuery.support/ . Jednak funkcja hashchange nie znajduje się na liście.

Wiki z modernizr oferuje listę bibliotek, aby dodać możliwości HTML5 do starych przeglądarek. Lista dla hashchange zawiera wskaźnik do projektu HTML5 History API , który wydaje się oferować funkcjonalność, co jest potrzebne, jeśli chciał naśladować zachowanie w starych przeglądarkach.

koppor
źródło
0

Oto zaktualizowana wersja @ johnny.rodgers

Nadzieja pomaga komuś.

// 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
źródło