jQuery - подія хеш-обміну


86

Я використовую:

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

прив’язати функцію до події зміни хешу. Здається, це працює в IE8, Firefox і Chrome, але не в Safari, і я припускаю, що не в попередній версії IE. Для цих браузерів я хочу відключити свій код JavaScript, який використовує хеш і hashchangeподію.

Чи є спосіб з jQuery, який я можу виявити, якщо браузер підтримує hashchangeподію? Може щось із jQuery.support...


4
Подія jQuery hashchange - плагін jQuery працює ідеально навіть у IE8. + ним дуже просто користуватися :)
enloz

Відповіді:


69

Ви можете визначити, чи підтримує браузер подію за допомогою:

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

Дивіться також:


Дякую за це та за швидку відповідь.
Ян Герберт

19
Зверніть увагу, що IE8, що працює в режимі сумісності IE7, повідомляє, що вікно відповідає дійсності для `` onhashchange '', хоча подія не підтримується -з jQuery Mobile
Vikas

36

Оновлена ​​відповідь тут станом на 2017 рік, якщо вона комусь потрібна, - це те, що onhashchangeдобре підтримується у всіх основних браузерах. Детальніше див. У каніусі . Щоб використовувати його з jQuery, плагін не потрібен:

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

Іноді я стикаюся із застарілими системами, де досі використовуються URL-адреси хеш-бангів, і це корисно. Якщо ви створюєте щось нове і використовуєте хеш-посилання, я настійно рекомендую вам використовувати замість цього API HTML5 pushState.


2
Це добре працює, використовуйте window.location.hashдля доступу до поточного хешу.
Деніел Дьюхерст


18

Інший підхід до вашої проблеми ...

Існує 3 способи прив’язати подію хеш-обміну до методу:

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

Або

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

Або

<body onhashchange="doThisWhenTheHashChanges();">

Всі вони працюють з IE 9, FF 5, Safari 5 та Chrome 12 на Win 7.


8

спробуйте офіційний сайт Mozilla: https://developer.mozilla.org/en/DOM/window.onhashchange

цитуйте наступним чином:

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

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

window.onhashchange = locationHashChanged;

3

Я просто зіткнувся з тією ж проблемою (відсутність події хеш-обміну в IE7). Обхідним шляхом, який підходив для моїх цілей, було прив’язати подію клацання посилань, що змінюють хеш.

<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
Ви можете використовувати $('a[href^="#"]')посилання на hrefs, які починаються з хешу, уникаючи необхідності додавати клас
tobymackenzie

2

Зверніть увагу, що у випадку з IE 7 та IE 9, якщо аргумент буде мати значення true ("onhashchange" у вікнах), але window.onhashchange ніколи не запускатиметься, тому краще зберігати хеш і перевіряти його через кожні 100 мілісекунд, чи змінено це чи ні для всіх версій 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
Хіба це не занадто багато для того, щоб браузер впорався? опитувати хеш-зміну кожні 100 мс?
adardesign

5
ваш зразок коду зробив моє попередження IE8, поки я не відкрив диспетчер завдань і не вбив процес :)
enloz

це тому, що є помилка, замість "storedHash" використовуйте "prevHash", і вона буде працювати. В основному він використовував інше ім'я змінної, ніж те, як воно було оголошено.
Nick

2

А як щодо використання іншого способу замість хеш-події та прослуховування popstate like.

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

Цей метод чудово працює в більшості браузерів, які я вже пробував.


1
Popstate ще новіший за хеш-обмін. Наприклад, це не підтримується в IE <10.
Артуро Торрес Санчес



0

Використовуйте Modernizr для виявлення функціональних можливостей. Загалом jQuery пропонує виявити функції браузера: http://api.jquery.com/jQuery.support/ . Однак hashchange у цьому списку немає.

Вікі з Modernizr пропонує список бібліотек для додавання можливості HTML5 в старих браузерах. Список для hashchange включає в себе покажчик на проект HTML5 History API , який , здається , щоб запропонувати функціональність вам буде потрібно , якщо ви хочете , щоб емулювати поведінка в старих браузерах.


0

Ось оновлена ​​версія @ johnny.rodgers

Надія комусь допомагає.

// 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);
}
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.