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

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

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

http://example.com/blah # 123 на http://example.com/blah # 456

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

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

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


person MilMike    schedule 25.03.2009    source источник
comment
Ознакомьтесь с этим плагином jquery: github.com/cowboy/jquery-hashchange   -  person Xavi    schedule 17.01.2011
comment
History.js поддерживает функцию управления состоянием HTML5 (поэтому вам больше не нужно использовать хеши. !) и изящно деградирует до браузеров HTML4, используя хеш-изменения. Он поддерживает jQuery, MooTools и Prototype из коробки.   -  person balupton    schedule 30.01.2011
comment
@balupton, на самом деле нам все еще нужно использовать хеши, чтобы сообщить пользователю, что в его историю была добавлена ​​новая страница, если вы не используете изменение URL-адреса в качестве обратной связи.   -  person Pacerier    schedule 12.10.2014
comment
[Hasher] github.com/millermedeiros/hasher   -  person Vishnoo Rath    schedule 15.01.2015
comment
хм ... Думаю, вам нужен более jQuery   -  person Penguin9    schedule 22.02.2017


Ответы (13)


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


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

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

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

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

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

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

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

person Community    schedule 25.03.2009
comment
Последняя сборка Firefox (3.6 альфа) теперь также поддерживает собственное событие изменения хэша: developer.mozilla .org / en / DOM / window.onhashchange Конечно, стоит проверить это событие, но обратите внимание, что IE8 сообщит вам, что событие существует, когда он запущен в режиме совместимости IE7 ... к сожалению, событие не t fire .. вам необходимо проверить событие и убедиться, что браузер не похож на IE7 .. вздох (или попытаться вызвать событие с помощью метода IE fireEvent). - person meandmycode; 18.08.2009
comment
На момент написания WebKit также запускает событие hashchange, а Safari (стабильный) еще не запускает. - person jholster; 20.04.2010
comment
В додзё то же самое: dojo.subscribe("/dojo/hashchange", context, callback); - person nilskp; 17.11.2011
comment
Чтобы добавить еще одно обновление, событие hashchange теперь широко поддерживается: caniuse.com/#search=hash - person Paystey; 12.03.2012
comment
Неужели я единственный, кто считает, что нежелательные ответы jQuery - это боль? - person Luc; 20.08.2012
comment
Не удалось заставить это работать с jQuery 1.7. Плагин не обновлялся за 2 года. - person Lèse majesté; 25.09.2012
comment
@Luc Я полностью с тобой согласен! Почему все полагают, что jQuery всегда используется! - person mmm; 19.07.2013
comment
@meandmycode могу ли я обнаружить изменение (window.location) и обработать его? (без jquery) - person BergP; 13.09.2013
comment
Этот ответ устарел - person ; 11.04.2014
comment
Но как узнать, когда будет доступен последний URL? - person VikkyB; 30.10.2014
comment
@Jhawins, какой новый ответ? - person SuperUberDuper; 19.03.2015
comment
@SuperUberDuper новый ответ находится под этим (прямая ссылка). Короче говоря, событие hashchange поддерживается всеми современными браузерами, и нет необходимости использовать специальный плагин событий jQuery, за исключением совместимости со старыми браузерами. Тем не менее, код в этом ответе в порядке и должен продолжать работать. - person ; 19.03.2015
comment
Отличный ответ, но не могли бы вы добавить информацию о том, как читать хэш-адрес этого события? - person zrajm; 23.02.2017

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

  • Internet Explorer 8
  • Firefox 3.6
  • Хром 5
  • Safari 5
  • Opera 10.6
person Miles    schedule 25.03.2009
comment
Обновление: FF 5, Safari 5 и Chrome 12 поддерживают это событие с июня 2011 года. - person james.garriss; 29.06.2011
comment
Вот страница CanIUse для хеш-обмена. Вот хеш-изменение в quirksmode. Поддержка IE ошибочна в отношении чувствительности к регистру. - person Tobu; 08.10.2011
comment
@everybody, не нужно добавлять к ответу в разделе комментариев - для этого и предназначена кнопка «Изменить». :) - person Michael Martin-Smucker; 15.06.2012
comment
использование: window.onhashchange = function() { doYourStuff(); } - person Chris; 10.08.2015
comment
Документация MDN для события hashchange. - person Dabowheel; 09.10.2015
comment
похоже, это не работает с манипуляциями с историей. есть window.onpopstate, но даже это не всегда сработает. - person cregox; 14.05.2017

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

person Khan Salahuddin    schedule 28.06.2011

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

person Sergio Cinos    schedule 30.10.2009

В Firefox с версии 3.6. См. window.onhashchange.

person edfuh    schedule 24.06.2010

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

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

person CJ.    schedule 19.10.2010
comment
Плагин Ben Alman, похоже, больше не поддерживается. Однако есть несколько вилок. - person Mnebuerquo; 08.07.2015

Вы можете легко реализовать наблюдателя (метод "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;

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

person gion_13    schedule 29.10.2010
comment
Лучше использовать: window.location.href вместо window.location. - person Codebeat; 11.05.2012
comment
Он смотрит window.location.hash, а не window.location. - person undefined; 26.09.2012
comment
@BrianMortenson: согласно документации (developer.mozilla. org / en-US / docs / JavaScript / Reference /) вы должны применить watch к объекту, которому принадлежит изменяемое свойство, и вы хотите наблюдать за ним. - person gion_13; 26.09.2012
comment
@ gion_13 Да, именно это я и пытался указать. Под «Он» я имел в виду вас, и это было направлено на комментарий Эрвинуса. Я должен был быть более ясным. Спасибо за разъясняющий комментарий. - person undefined; 26.09.2012

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

Я наблюдал за параметром хеширования, используя

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

потом

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

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

person Sprose    schedule 07.12.2017
comment
в вашем addEventListener вызове вы должны удалить () из doSomethingWithChangeFunction - person Jason S; 29.10.2018
comment
Можете ли вы указать причину удаления ()? Я знаю, что он будет работать и с тем, и с другим, и меньше кода - лучший вариант, но это кажется придирчивым, если нет веской причины для его поддержки? - person Sprose; 07.11.2018
comment
? он не должен работать с (). Функция addEventListener требует, чтобы вы передали функцию. doSomethingWithChangeFunction - это функция. doSomethingWithChangeFunction() - это возвращаемое значение этой функции, которая в данном случае не является функцией. - person Jason S; 07.11.2018


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

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

person balupton    schedule 28.08.2010

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

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

person batman    schedule 25.02.2011

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

path.js NPM

path.js GitHub

person Tom    schedule 02.01.2015

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

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

person moha297    schedule 28.12.2009