On - window.location.hash - Изменить?

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

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

http://example.com/blah # 123 в http://example.com/blah # 456

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

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

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

Ответ 1

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


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

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

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

Приятно, что здесь вы можете написать код, который не нуждается даже в том, чтобы беспокоиться о поддержке hashchange, однако вам нужно сделать какую-то магию в виде несколько менее известной функции jQuery специальные события jQuery.

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

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

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

Ответ 3

Обратите внимание, что в случае Internet Explorer 7 и Internet Explorer 9 статус if даст true (для "onhashchange" в окнах), но 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/

Ответ 4

Есть много трюков, связанных с историей и 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 хранятся в истории только в том случае, если элементы '< a name= "# b" > ' и '< a name= "# c" > ' существует ранее на странице.

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

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

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

Ответ 5

У Firefox было событие onhashchange с 3.6. См. window.onhashchange.

Ответ 6

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

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

Ответ 7

Вы можете легко реализовать наблюдателя (метод "смотреть" ) по свойству "хэш" объекта "window.location".

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

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

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

Затем вы можете проверить его:

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

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

Ответ 8

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

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

Ответ 9

Еще одна отличная реализация - jQuery History, которая будет использовать собственное событие onhashchange, если оно поддерживается браузером, если оно не будет использоваться iframe или интервал для браузера, чтобы гарантировать, что все ожидаемые функциональные возможности успешно эмулируются. Он также обеспечивает хороший интерфейс для привязки к определенным состояниям.

Еще один заслуживающий внимания проект - jQuery Ajaxy, который в значительной степени является расширением для истории jQuery для добавления ajax в микс. Когда вы начинаете использовать ajax с хешами, он довольно сложный!

Ответ 10

var page_url = 'http://www.yoursite.com/'; // full path leading up to hash;
var current_url_w_hash = page_url + window.location.hash; // now you might have something like: http://www.yoursite.com/#123

function TrackHash() {
    if (document.location != page_url + current_url_w_hash) {
        window.location = document.location;
    }
    return false;
}
var RunTabs = setInterval(TrackHash, 200);

Чтобы он... теперь, когда вы нажимаете кнопки "Назад" или "Назад", страница перезагружается в соответствии с новым значением хэша.

Ответ 11

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

path.js NPM

path.js GitHub

Ответ 12

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

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

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

Тогда

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

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

Ответ 13

Я использовал плагин jQuery, HUtil и написал YUI История, как интерфейс поверх нее.

Проверьте его один раз. Если вам нужна помощь, я могу помочь.