jQuery - acara hashchange

86

Saya menggunakan:

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

untuk mengikat fungsi ke acara perubahan hash. Ini tampaknya berfungsi di IE8, Firefox dan Chrome, tetapi tidak di Safari dan saya berasumsi tidak di versi IE sebelumnya. Untuk browser ini, saya ingin menonaktifkan kode JavaScript saya yang menggunakan hash danhashchange event.

Apakah ada cara dengan jQuery yang saya dapat mendeteksi jika browser mendukung hashchangeacara tersebut? Mungkin sesuatu dengan jQuery.support...

Ian Herbert
sumber
4
Acara hashchange jQuery - plugin jQuery bekerja dengan sempurna, bahkan di IE8. + sangat mudah untuk menggunakannya :)
enloz

Jawaban:

69

Anda dapat mendeteksi apakah browser mendukung acara tersebut dengan:

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

Lihat juga:

Christian C. Salvadó
sumber
Terima kasih untuk itu dan untuk tanggapan yang cepat.
Ian Herbert
19
Perhatikan bahwa IE8 yang berjalan dalam mode kompatibilitas IE7 melaporkan true untuk 'onhashchange' di jendela, meskipun peristiwa tersebut tidak didukung -dari jQuery Mobile
Vikas
37

Jawaban yang diperbarui di sini pada tahun 2017, jika ada yang membutuhkannya, apakah itu onhashchangedidukung dengan baik di semua browser utama. Lihat caniuse untuk detailnya. Untuk menggunakannya dengan jQuery tidak diperlukan plugin:

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

Kadang-kadang saya menemukan sistem lama di mana URL hashbang masih digunakan dan ini sangat membantu. Jika Anda sedang membangun sesuatu yang baru dan menggunakan tautan hash, saya sangat menyarankan Anda untuk mempertimbangkan menggunakan API pushState HTML5 sebagai gantinya.

Kevin Leary
sumber
2
Ini berfungsi dengan baik, gunakan window.location.hashuntuk mengakses hash saat ini.
Daniel Dewhurst
18

Ada plug-in hashchange yang membungkus fungsionalitas dan masalah lintas browser yang tersedia di sini .

James Westgate
sumber
Hanya diperlukan untuk <IE8
James Westgate
18

Pendekatan berbeda untuk masalah Anda ...

Ada 3 cara untuk mengikat peristiwa hashchange ke sebuah metode:

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

Atau

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

Atau

<body onhashchange="doThisWhenTheHashChanges();">

Ini semua bekerja dengan IE 9, FF 5, Safari 5, dan Chrome 12 di Win 7.

james.garriss
sumber
8

coba situs resmi Mozilla: https://developer.mozilla.org/en/DOM/window.onhashchange

mengutip sebagai berikut:

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

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

window.onhashchange = locationHashChanged;
Paul Lan
sumber
3

Saya baru saja mengalami masalah yang sama (kurangnya acara hashchange di IE7). Solusi yang cocok untuk tujuan saya adalah dengan mengikat peristiwa klik pada tautan pengubah 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
sumber
1
Anda dapat menggunakan $('a[href^="#"]')untuk mendapatkan tautan yang hrefdimulai dengan hash, menghindari kebutuhan untuk add kelas
tobymackenzie
2

Perhatikan bahwa dalam kasus IE 7 dan IE 9 jika statment akan memberikan true untuk ("onhashchange" di windows) tetapi window.onhashchange tidak akan pernah menyala, jadi lebih baik untuk menyimpan hash dan memeriksanya setelah setiap 100 milidetik apakah itu berubah atau tidak untuk semua versi 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
sumber
2
Bukankah ini terlalu berat untuk ditangani browser? melakukan polling untuk perubahan hash setiap 100 md?
adardesign
5
kode sampel Anda membuat IE8 saya memberi tahu sampai saya membuka task manager dan proses mematikan :)
enloz
itu karena ada kesalahan ketik, alih-alih "storedHash" gunakan "prevHash" dan ini akan berhasil. Dia pada dasarnya menggunakan nama variabel yang berbeda dari yang dideklarasikan.
Nick
2

Bagaimana dengan menggunakan cara yang berbeda daripada acara hash dan mendengarkan popstate seperti.

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

Metode ini berfungsi dengan baik di sebagian besar browser yang telah saya coba sejauh ini.

Sven van den Boogaart
sumber
1
Popstate bahkan lebih baru dari hashchange. Misalnya, ini tidak didukung di IE <10.
Arturo Torres Sánchez
0

Saya pikir Chris Coyier memiliki solusi untuk masalah hashing itu, lihat screencastnya:

Praktik Terbaik dengan Konten Dinamis

Sarfraz
sumber
Terima kasih, saya akan memeriksanya.
Ian Herbert
0

Berikut adalah versi terbaru dari @ johnny.rodgers

Harapan membantu seseorang.

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