elt.innerHTML = msg; // Отобразить информацию о местонахождении
}
}
22.2. Управление историей посещений
Веб-броузеры запоминают, какие документы загружались в окно, и предоставляют кнопки Back и Forward, позволяющие перемещаться между этими документами. Эта модель хранения истории посещений в броузерах появилась еще в те дни, когда документы были статическими и все вычисления выполнялись на стороне сервера. В настоящее время веб-приложения часто загружают содержимое динамически и отображают новые состояния приложения без полной перезагрузки документа. Такие приложения должны предусматривать собственные механизмы
управления историей посещений, если необходимо дать пользователю возможность использовать кнопки Back и Forward для перехода из одного состояния приложения в другое интуитивно понятным способом. Спецификация HTML5 определяет два механизма управления историей посещений.
Простейший способ работы с историей посещений связан с использованием свойства
location.hash
и события «hashchange». На момент написания этих строк данный способ был также наиболее широко реализованным: его поддержка в броузерах появилась еще до того, как он был стандартизован спецификацией HTML5. В большинстве броузеров (кроме старых версий IE) изменение свойства
location.hash
приводит к изменению URL, отображаемого в строке ввода адреса, и добавлению записи в историю посещений. Свойство
hash
определяет идентификатор фрагмента в URL и традиционно использовалось для перемещения к разделу документа с указанным идентификатором. Но свойство
location.hash
не обязательно должно определять идентификатор элемента: в него можно записать произвольную строку. Если состояние приложения можно представить в виде строки, эту строку можно будет использовать как идентификатор фрагмента.
Предусмотрев изменение значения свойства
location.hash
, вы даете пользователю возможность использовать кнопки Back и Forward для перемещения между состояниями приложения. Чтобы такие перемещения были возможны, приложение должно иметь способ определять момент изменения состояния, прочитать строку, хранящуюся в виде идентификатора фрагмента, и обновить себя в соответствии с требуемым состоянием. Согласно спецификации HTML5, при изменении идентификатора фрагмента броузер должен возбуждать событие «hashchange» в объекте
Window
. В броузерах, поддерживающих событие «hashchange», можно присвоить свойству
window.onhashchange
функцию обработчика, которая будет вызываться при каждом изменении идентификатора фрагмента документа, вызванном перемещением по истории посещений. При вызове эта функция-обработчик должна проанализировать значение
location.hash
и отобразить содержимое страницы, соответствующее выбранному состоянию.
Спецификация HTML5 также определяет другой, более сложный и более надежный способ управления историей посещений, основанный на использовании метода
history.pushState
и события «popstate». При переходе в новое состояние вебприложение может вызвать метод
history.pushState
, чтобы добавить это состояние в историю посещений. В первом аргументе методу передается объект, содержащий всю информацию, необходимую для восстановления текущего состояния приложения. Для этой цели подойдет любой объект, который можно преобразовать в строку вызовом метода
JSON.stringify,
а также некоторые встроенные типы, такие как
Date
и
RegExp
(смотрите врезку ниже). Во втором аргументе передается необязательное заглавие (простая текстовая строка), которую броузер сможет использовать для идентификации сохраненного состояния в истории посещений (например, в меню кнопки Back). В третьем необязательном аргументе передается строка URL, которая будет отображаться как адрес текущего состояния. Относительные URL-адреса интерпретируются относительно текущего адреса документа и нередко определяют лишь часть URL, соответствующую идентификатору фрагмента, такую как #state. Связывание различных состояний приложения с собственными URL-адресами дает пользователю возможность делать закладки на внутренние состояния приложения, и если в строке URL будет указан достаточное количество информации, приложение сможет восстановить это состояние при запуске с помощью закладки.
Структурированные копии
Как отмечалось выше, метод pushState принимает объект с информацией о состоянии и создает его частную копию. Это полная, глубокая копия объекта: при ее создании рекурсивно копируется содержимое всех вложенных объектов и массивов. В стандарте HTML5 такие копии называются структурированными копиями. Процедура создания структурированной
копии напоминает передачу объекта функции JSON. stringif у и обработку результата функцией JSON.parse (раздел 6.9). Но в формат JSON можно преобразовать только простые значения JavaScript, а также объекты и массивы. Стандарт HTML5 требует, чтобы алгоритм создания структурированных копий поддерживал возможность создания копий объектов Date и RegExp, ImageData (полученных из элементов <canvas> - раздел 21.4.14) и FileList, File и Blob (описывается в разделе 22.6). Функции JavaScript и объекты ошибок явно исключены из списка объектов, поддерживаемых алгоритмом создания структурированных копий, также как и большинство объектов среды выполнения, таких как окна, документы, элемент и т. д.
Вряд ли вам понадобится сохранять файлы или изображения как часть состояния приложения, однако структурированные копии также используются некоторыми другими стандартами, связанными со стандартом HTML5, и мы будем встречать их на протяжении всей этой главы.
***********************************************
В дополнение к методу
pushState
объект
History
определяет метод
replaceState,
который принимает те же аргументы, но не просто добавляет новую запись в историю посещений, а замещает текущую запись.
Когда пользователь перемещается по истории посещений с помощью кнопок Back и Forward, броузер возбуждает событие «popstate» в объекте
Window
. Объект, связанный с этим событием, имеет свойство с именем
state
, содержащее копию (еще одну структурированную копию) объекта с информацией о состоянии, переданного методу
pushState.
В примере 22.3 демонстрируется простое веб-приложение - игра «Угадай число», изображенная на рис. 22.1, - в которой используются описанные приемы сохранения истории посещений, определяемые стандартом HTML5, с целью дать пользователю возможность «вернуться назад», чтобы пересмотреть или повторить попытку.
Когда эта книга готовилась к печати, в броузере Firefox 4 было внесено два изменения в прикладной интерфейс объекта
History
, которые могут быть заимствованы и другими броузерами. Во-первых, в Firefox 4 информация о текущем состоянии теперь доступна через свойство
state
самого объекта
History
, а это означает, что вновь загружаемые страницы не должны ждать события «popstate». Во-вторых, Firefox 4 более не возбуждает событие «popstate» для вновь загруженных страниц, для которых отсутствует сохраненное состояние. Это второе изменение означает, например, что пример, приведенный ниже, будет работать неправильно в Firefox 4.
Примерх 22.3. Управление историей посещений с помощью pushStatef
<!DOCTYPE html>
<html><head><title>I'm thinking of a number...</title>
<script>
window.onload = newgame; // Начать новую игру при загрузке
window.onpopstate = popstate; // Обработчик событий истории посещений
var state, ui; // Глобальные переменные, инициализируемые в функции newgame
function newgame(playagain) { // Начинает новую игру "Угадай число"
// Настроить объект для хранения необходимых элементов документа
ui = {
heading: null, // Заголовок <h1> в начале документа.
prompt: null, // Текст предложения ввести число.
input: null, // Поле, куда пользователь вводит-числа.
low: null, // Три ячейки таблицы для визуального представления
mid: null, // ...диапазона, в котором находится загаданное число.