Ведение истории изменений хеша / якоря в JavaScript

В настоящее время я реализую библиотеку JavaScript, которая отслеживает историю изменений в хэш-части в адресной строке. Идея состоит в том, что вы можете сохранить состояние в хеш-части, а затем использовать кнопку "Назад" для возврата в предыдущее состояние.

В большинстве последних браузеров это происходит автоматически, и вам нужно только опросить location.hash свойство для изменений (в IE8 вам даже не нужно это делать; вы просто присоединяете функцию к onhashchange событие.)

Что мне интересно, так это то, что существуют разные методы для отслеживания истории? Я реализовал функциональность, которая была протестирована для работы в Internet Explorer 6/7/8, Firefox и Chrome, но как насчет других браузеров? Вот как я сейчас храню историю:

Изменить: см. Мой ответ ниже для просмотра различных браузеров.

5 ответов

Решение

Прежде всего, спасибо вам, ребята, которые ответили! знак равно

Сейчас я провел гораздо больше исследований, и я считаю, что доволен своей реализацией. Вот результаты моего исследования.

Прежде всего, мой закончил Hash библиотека Это отдельная библиотека без зависимостей. У него две функции: Hash.init(callback, iframe) а также Hash.go(newHash), Функция обратного вызова вызывается всякий раз, когда хэш изменяется с новым хешем в качестве первого аргумента, а в качестве второго аргумента указывается флаг, указывающий, вызывается ли обратный вызов из-за начального состояния (true) или фактическое изменение хеша (false).

Hash.js (лицензия MIT)

Я также сделал плагин jQuery для облегчения использования. Добавляет глобальный hashchange событие также. Смотрите пример в исходном коде, чтобы узнать, как его использовать.

jquery.hash.js (лицензия MIT)

Чтобы увидеть их в действии, перейдите на мою страницу JavaScript "realm":

JavaScript-сфера Blixt

Internet Explorer 8

Smooooth круиз! Просто чмокнуть их onhashchange события в window объект (используя attachEvent) и получить location.hash значение в обработчике события.

Неважно, щелкнет ли пользователь по ссылке с помощью хеша, или если вы установите хеш программно; история хранится отлично.

Chrome, Firefox, Safari 3+, Opera 8+

Плавный круиз! Просто опрос на предмет изменений location.hash использование имущества setInterval и функция.

История работает отлично. Для Opera я установил history.navigationMode в 'compatible', Если честно, я не уверен, что он делает, я сделал это по рекомендации из комментария в коде YUI.

Примечание: Opera нуждается в дополнительном тестировании, но до сих пор она работала нормально для меня.

Сюрприз, необычный бонус! (Может ли это быть?!) Оказывается, что Firefox (только подтвержденный в 3.5+) декодирует location.hash свойство, так что это может вызвать hashchange событие дважды (сначала для закодированной версии, затем для некодированной версии.) Существует новая версия моей библиотеки Hash.js, которая учитывает это с помощью location.href свойство вместо (изменения предоставлены Aaron Ogle.)

Internet Explorer 6, 7

Теперь это становится противнее. История навигации в более старых версиях Internet Explorer игнорирует изменения хеша. Чтобы обойти это, общепринятым решением является создание iframe и установите его содержимое в новый хэш. Это создает новую запись в истории навигации. Когда пользователь возвращается, это меняет содержание iframe к своему предыдущему содержанию. Обнаружив изменение содержимого, вы можете получить его и установить в качестве активного хэша.

Проверка на наличие изменений в location.hash свойство все еще необходимо для ручного изменения текущего адреса. Остерегайтесь причуд, которые я упомянул ниже, хотя.

Хотя это решение кажется лучшим из всех, оно все еще не идеально в Internet Explorer 6, что немного странно с кнопками "назад" и "вперед". Internet Explorer 7 работает нормально, хотя.

Сюрприз, необычный бонус #1! В Internet Explorer 6 всякий раз, когда в хэше есть знак вопроса, он извлекается и помещается в location.search имущество! Это удалено из location.hash имущество. Если есть реальная строка запроса, однако, location.search вместо этого будет содержать этот, и вы сможете получить весь истинный хеш, анализируя location.href имущество.

Сюрприз, необычный бонус #2! Если location.search свойство установлено, любое последующее # символы будут удалены из location.href (а также location.hash ) имущество. В Internet Explorer 6 это означает, что всякий раз, когда в пути или хэше есть вопросительный знак, вы будете испытывать эту причуду. В Internet Explorer 7 эта причуда возникает только тогда, когда в пути есть вопросительный знак. Разве вы не любите последовательность в Internet Explorer?

Сюрприз, необычный бонус #3! Если другой элемент на странице имеет тот же идентификатор, что и значение хеша, этот хеш полностью испортит историю. Поэтому практическое правило заключается в том, чтобы избегать хэшей с тем же идентификатором, что и любые элементы на странице. Если хеши генерируются динамически и могут конфликтовать с идентификаторами, рассмотрите возможность использования префикса / суффикса.

Другие браузеры

Если у вас нет необычной пользовательской базы, вам не нужно будет поддерживать больше браузеров. Браузеры, не перечисленные выше, относятся к категории использования <1%.

Основываясь на ваших усилиях, я бы предположил, что вы видели YUI Browser History Manager, но на всякий случай...

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

Вот что это говорит об Опере

* location.hash is a bit buggy on Opera. I have seen instances where
* navigating the history using the back/forward buttons, and hence
* changing the URL, would not change location.hash. That's ok, the
* implementation of an equivalent is trivial ... more below

В поисках источника я также нашел несколько мест для Safari 1.x & 2.0. Похоже, тебе это будет интересно.

Надеюсь, это поможет.

Я не уверен, что полностью понимаю ваши потребности, но я использовал библиотеку Really Simple History ( http://code.google.com/p/reallysimplehistory/) для реализации чего-то подобного. Вы можете увидеть это здесь: http://whiteoak.sourceforge.net/

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

В IE (проверено только в IE7) история с хешем работает правильно, когда на экране есть элемент страницы с идентификатором, равным хешу. Например, подумайте о содержании (TOC) на странице вики. Каждая ссылка в оглавлении ссылается на хеш элемента id или имени якоря где-то на странице:

<div id="TOC">
<a id="SampleHeaderLink" href="#SampleHeader">Sample Header</a>
</div>

<h2 id="SampleHeader">Sample Header</a>

Поэтому при щелчке SampleHeaderLink по умолчанию в браузере IE устанавливается навигация к SampleHeader и регистрация состояния в истории. Использование кнопок "Назад" и "Вперед" работает как положено.

Однако, если div SampleHeader не существует на странице, браузер только регистрирует изменение URL-адреса, но не создает для него новое состояние.

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

GWT обеспечивает управление историей. Это также неотъемлемая часть их структуры MVP. Они также расширили API истории с местами и действиями.

Другие вопросы по тегам