On - window.location.hash - Изменить? - PullRequest
540 голосов
/ 25 марта 2009

Я использую Ajax и хэш для навигации.

Есть ли способ проверить, изменился ли window.location.hash следующим образом?

http://example.com/blah#123 до http://example.com/blah#456

Это работает, если я проверяю его при загрузке документа.

Но если у меня есть навигация на основе #hash, она не работает, когда я нажимаю кнопку возврата в браузере (поэтому я перехожу с бла # 456 на бла # 123).

Он отображается внутри адресной строки, но я не могу поймать его с помощью JavaScript.

Ответы [ 13 ]

603 голосов
/ 25 марта 2009

Единственный способ действительно сделать это (и как «действительно простая история» делает это), это установить интервал, который продолжает проверять текущий хеш, и сравнивать его с тем, что было раньше, мы делаем это и позволяем подписчикам подписываться к измененному событию, которое мы запускаем при изменении хеша ... оно не идеально, но браузеры действительно не поддерживают это событие изначально.


Обновление, чтобы сохранить этот ответ свежим:

Если вы используете jQuery (который сегодня должен быть несколько основополагающим для большинства), то хорошим решением будет использование абстракции, которую дает вам jQuery, используя свою систему событий для прослушивания событий hashchange в объекте окна.

$(window).on('hashchange', function() {
  //.. work ..
});

Приятно то, что вы можете писать код, который не должен беспокоиться о поддержке хеширования, однако вам НЕОБХОДИМО сделать некоторую магию в виде менее известной функции jQuery специальные события jQuery .

С помощью этой функции вы, по сути, можете запускать некоторый установочный код для любого события, когда кто-то впервые пытается использовать событие каким-либо образом (например, привязку к событию).

В этом коде настройки вы можете проверить поддержку встроенного браузера, а если браузер не реализует это встроенным образом, вы можете настроить один таймер для запроса изменений и вызвать событие jQuery.

Это полностью освобождает ваш код от необходимости понимать эту проблему поддержки, реализация специального события такого рода тривиальна (для получения простой 98% рабочей версии), но зачем это делать , когда кто-то уже имеет .

282 голосов
/ 25 марта 2009

HTML5 указывает hashchange событие . Это событие теперь поддерживается всеми современными браузерами . Поддержка была добавлена ​​в следующих версиях браузера:

  • Internet Explorer 8
  • Firefox 3.6
  • Chrome 5
  • Safari 5
  • Опера 10,6
50 голосов
/ 28 июня 2011

Обратите внимание, что в случае Internet Explorer 7 и Internet Explorer 9 для if будет указано значение true (для «onhashchange» в windows), но window.onhashchange никогда не сработает, поэтому лучше хранить хэш и проверять его после каждых 100 миллисекунд, независимо от того, изменяется оно или нет для всех версий Internet Explorer.

    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);
    }

РЕДАКТИРОВАТЬ - Начиная с jQuery 1.9, $.browser.msie не поддерживается. Источник: http://api.jquery.com/jquery.browser/

14 голосов
/ 30 октября 2009

Есть много хитростей, чтобы разобраться с History и window.location.hash в браузерах IE:

  • Как сказал оригинальный вопрос, если вы перейдете со страницы a.html # b на a.html # c, а затем нажмете кнопку «Назад», браузер не узнает, что страница изменилась. Позвольте мне сказать это на примере: window.location.href будет «a.html # c», независимо от того, находитесь ли вы в a.html # b или a.html # c.

  • На самом деле, a.html # b и a.html # c хранятся в истории только , если элементы '' и ' 'ранее существовал на странице.

  • Однако, если вы поместите iframe на страницу, перейдите от a.html # b к a.html # c в этом iframe, а затем нажмите кнопку «Назад», если iframe.contentWindow.document.location.href изменится как и ожидалось.

  • Если вы используете «document.domain = что-то » в своем коде, то вы не сможете получить доступ к iframe.contentWindow.document.open () '(и многие Менеджеры истории делают это )

Я знаю, что это не настоящий ответ, но, возможно, заметки IE-History кому-нибудь пригодятся.

12 голосов
/ 24 июня 2010

Firefox имеет событие onhashchange начиная с 3.6. См. window.onhashchange .

11 голосов
/ 19 октября 2010

Бен Алман имеет отличный плагин jQuery для решения этой проблемы: http://benalman.com/projects/jquery-hashchange-plugin/

Если вы не используете jQuery, это может быть интересной ссылкой для анализа.

9 голосов
/ 29 октября 2010

Вы можете легко реализовать наблюдателя (метод watch) для свойства hash объекта window.location.

Firefox имеет собственную собственную реализацию для отслеживания изменений объекта , но если вы используете какую-то другую реализацию (например, Отслеживайте изменения свойств объекта в JavaScript ) - для других браузеров это поможет.

Код будет выглядеть так:

window.location.watch(
    'hash',
    function(id,oldVal,newVal){
        console.log("the window's hash value has changed from "+oldval+" to "+newVal);
    }
);

Тогда вы можете проверить это:

var myHashLink = "home";
window.location = window.location + "#" + myHashLink;

И, конечно, это активирует функцию наблюдателя.

6 голосов
/ 07 декабря 2017

Я использовал это в приложении реагирования, чтобы URL отображал различные параметры в зависимости от того, какой вид был у пользователя.

Я смотрел параметр хэша, используя

window.addEventListener('hashchange', doSomethingWithChangeFunction());

Тогда

doSomethingWithChangeFunction () { 
    // Get new hash value
    let urlParam = window.location.hash;
    // Do something with new hash value
};

Работал лакомством, работает с кнопками браузера вперед и назад, а также в истории браузера.

6 голосов
/ 25 марта 2009

Достойную реализацию можно найти на http://code.google.com/p/reallysimplehistory/. Единственная (но также) проблема и ошибка, которые у него есть: в Internet Explorer изменение хэша местоположения вручную сбросит весь стек истории (это проблема браузера, и она не может быть решена).

Обратите внимание: Internet Explorer 8 поддерживает событие hashchange, и, поскольку оно становится частью HTML5, вы можете ожидать, что другие браузеры его догонят.

1 голос
/ 03 января 2015

Я использовал path.js для маршрутизации на стороне клиента. Я нашел его довольно лаконичным и легким (он также был опубликован в NPM) и использует навигацию на основе хеша.

path.js NPM

path.js GitHub

...