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

490

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

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

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

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

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

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

  • 6
    Оформить заказ на этот плагин jquery: github.com/cowboy/jquery-hashchange
  • 9
    History.js поддерживает функциональность управления состоянием HTML5 (поэтому вам больше не нужно использовать хэши!) И изящно разлагает его до браузеров HTML4 с помощью хэш-хангов. Он поддерживает jQuery, MooTools и Prototype из коробки.
Показать ещё 3 комментария
Теги:
javascript-events
fragment-identifier
hashchange

13 ответов

616
Лучший ответ

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


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

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

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

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

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

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

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

  • 7
    IE8 делает. Еще не все
  • 28
    Последняя сборка Firefox (версия 3.6) также теперь поддерживает встроенное событие изменения хеша: developer.mozilla.org/en/DOM/window.onhashchange Конечно, стоит проверить это событие, но обратите внимание, что IE8 сообщит вам об этом событии. существует, когда он работает в режиме сравнения IE7 .. к сожалению, событие не запускается .. вам нужно проверить событие и что браузер не выглядит как IE7 .. sigh (или попытаться вызвать событие с помощью метода IE fireEvent).
Показать ещё 13 комментариев
267

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

  • Internet Explorer 8
  • Firefox 3.6
  • Chrome 5
  • Safari 5
  • Opera 10.6
  • 20
    Обновление: FF 5, Safari 5 и Chrome 12 поддерживают это событие с июня 2011 года.
  • 1
    Вот страница CanIUse для хэширования . Вот hashchange на причудливый режим . Поддержка IE глючит в отношении чувствительности к регистру.
Показать ещё 4 комментария
46

Обратите внимание, что в случае 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/

13

Есть много трюков, связанных с историей и 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 полезны для кого-то.

12

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

11

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

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

  • 0
    Плагин Ben Alman, похоже, больше не поддерживается. Хотя есть несколько вилок.
9

Вы можете легко реализовать наблюдателя (метод "смотреть" ) по свойству "хэш" объекта "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;

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

  • 0
    Лучше использовать: window.location.href вместо window.location.
  • 2
    Он смотрит window.location.hash, а не window.location.
Показать ещё 2 комментария
6

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

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

1

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

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

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

Тогда

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

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

  • 0
    в вашем вызове addEventListener вы должны удалить () из doSomethingWithChangeFunction
  • 0
    Можете ли вы указать причину удаления ()? Я знаю, что это будет работать с любым из них, и меньший код в большинстве случаев является лучшим вариантом, но это кажется придирчивым, если нет веских оснований для этого?
Показать ещё 1 комментарий
1

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

path.js NPM

path.js GitHub

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

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

  • 0
    не используйте пробные строки
1

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

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

0

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

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

Ещё вопросы

Сообщество Overcoder
Наверх
Меню