jQuery - событие hashchange


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, сообщает true для 'onhashchange' в окне, даже если событие не поддерживается - из jQuery Mobile
Викас

36

Обновленный ответ здесь по состоянию на 2017 год, если он кому-то понадобится, onhashchangeхорошо поддерживается во всех основных браузерах. См. Caniuse для подробностей. Чтобы использовать его с jQuery, плагин не нужен:

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

Иногда я сталкиваюсь с устаревшими системами, в которых все еще используются URL-адреса hashbang, и это полезно. Если вы создаете что-то новое и используете хеш-ссылки, я настоятельно рекомендую вам рассмотреть возможность использования вместо этого HTML5 pushState API.


2
Это хорошо работает, используйте window.location.hashдля доступа к текущему хешу.
Дэниел Дьюхерст


18

Другой подход к вашей проблеме ...

Есть 3 способа привязать событие hashchange к методу:

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



3

Я столкнулся с той же проблемой (отсутствие события hashchange в IE7). Обходной путь, который подходил для моих целей, заключался в привязке события click для ссылок, изменяющих хэш.

<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, если статус будет верен для ("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 06

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

это потому, что есть опечатка, вместо «storedHash» используйте «prevHash», и это сработает. Он в основном использовал имя переменной, отличное от того, как оно было объявлено.
Ник

2

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

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

Этот метод отлично работает в большинстве браузеров, которые я пробовал до сих пор.


1
Popstate даже новее, чем hashchange. Например, он не поддерживается в 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.