Ведение истории изменений хеша / якоря в 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":
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 истории с местами и действиями.