Введение в HTML5 History API
До появления HTML5 единственное, что мы не могли контролировать и управлять (без перезагрузки контента или хаков с location.hash) — это история одного таба. С появлением HTML5 history API все изменилось — теперь мы можем гулять по истории (раньше тоже могли), добавлять элементы в историю, реагировать на переходы по истории и другие полезности. В этой статье мы рассмотрим HTML5 History API и напишем простой пример, иллюстрирующий его возможности.
Основные понятия и синтаксис
History API опирается на один DOM интерфейс — объект History. Каждый таб имеет уникальный объект History, который находится в window.history . History имеет несколько методов, событий и свойств, которыми мы можем управлять из JavaScript. Каждая страница таба(Document object) представляет собой объект коллекции History. Каждый элемент истории состоит из URL и/или объекта состояния (state object), может иметь заголовок (title), Document object, данные форм, позиция скролла и другую информацию, связанную со страницей.
- window.history.length : Количество записей в текущей сессии истории
- window.history.state : Возвращает текущий объект истории
- window.history.go(n) : Метод, позволяющий гулять по истории. В качестве аргумента передается смещение, относительно текущей позиции. Если передан 0, то будет обновлена текущая страница. Если индекс выходит за пределы истории, то ничего не произойдет.
- window.history.back() : Метод, идентичный вызову go(-1)
- window.history.forward() : Метод, идентичный вызову go(1)
- window.history.pushState(data, title [, url]) : Добавляет элемент истории.
- window.history.replaceState(data, title [, url]) : Обновляет текущий элемент истории
history.pushState(, 'Title', '/baz.html')
history.replaceState(, 'New Title')
Живой пример
Теперь мы знаем основы, давайте посмотрим на живой пример. Мы будем делать веб файловый менеджер, который позволит вам найти URI выбранного изображения(посмотрите то, что получится в конце). Файловый менеджер использует простую файловую структуру, написанную на JavaScript. Когда вы выбираете файл или папку картинка динамически обновляется.
Мы используем data-* атрибуты для хранения заголовка каждой картинки и используем свойство dataset для получения этого свойства:
Чтобы все работало быстро мы подгружаем все картинки и обновляем атрибут src динамически. Это ускорение создает одну проблему — оно ломает кнопку назад, поэтому вы не можете переходить по картинками вперед или назад.
HTML5 history приходит на помощь! Каждый раз когда мы выбираем файл создается новая запись истории и location документа обновляется (оно содержит уникальный URL картинки). Это означает, что мы можем использовать кнопку назад для обхода наших изображений, в то время как в строке адреса у нас будет прямая ссылка на картинку, которую мы можем сохранить в закладки или отправить кому-либо.
Код
У нас есть 2 дива. Один содержит структуру папок, другой содержит текущую картинку. Все приложение управляется с помощью JavaScript. В будут освещены только самые важные моменты. Исходный код примера очень короткий (порядка 80 строк) посмотрите его после прочтения всей статьи.
Метод bindEvents навешивает обработчики для события popstate , который вызывается, когда пользователь переходит по истории и позволяет приложению обновлять свое состояние.
window.addEventListener('popstate', function(e)< self.loadImage(e.state.path, e.state.note); >, false);
Объект event , который передается в обработчик события popstate имеет свойство state — это данные, которые мы передали в качестве первого аргумента pushState или replaceState .
Мы навешиваем обработчик на событие click на див, который представляет нашу файловую структуру. Используя делегацию событий, мы открываем или закрываем папку или загружаем картинку (с добавлением записи в историю). Мы смотрим на className родительского элемента для того, чтобы понять на какой из элементов мы нажали:
— Если это папка мы открываем или закрываем её
— Если это картина, то мы показываем её и добавляем элемент истории
dir.addEventListener('click', function(e) < e.preventDefault(); var f = e.target; // Это папка if (f.parentNode.classList.contains('folder')) < // Открываем или закрываем папку self.toggleFolders(f); >// Это картинка else if (f.parentNode.classList.contains('photo'))< note = f.dataset ? f.dataset.note : f.getAttribute('data-note'); // отрисовываем картинку self.loadImage(f.textContent, note); // добавляем элемент истории history.pushState(, '', f.textContent); > >, false);
loadImage: function(path, note)
Мы получили простое приложение, демонстрирующее возможности обновленного интерфейса объекта History . Мы используем pushState для добавления элемента истории и событие popstate для обновления содержимого страницы. Кроме этого при клике на картинку мы получаем в адресной строке её действительный адрес, который мы можем сохранить или отправить кому-нибудь.
Когда можно будет использовать?
Firefox 4+
Safari 5+
Chrome 10+
Opera 11.5+
iOS Safari 4.2+
Android 2.2+
IE .
Список браузеров, поддерживающих history API
Где это используется?
1. Facebook
2. Github — навигация по дереву проекта
3. .
Объект History в JavaScript — история просмотра страниц
Объект history отвечает за историю переходов, которые пользователь совершил в переделах одного окна или вкладки браузера. Эти переходы браузер сохраняет в сессию истории текущего окна (вкладки) и пользователь с помощи кнопки «Назад» всегда может вернуться на предыдущие страницы. Кроме кнопки «Назад» пользователю доступна ещё кнопка «Вперёд», которая предназначена для того, чтобы пользователь мог вернуться обратно на страницы, с которых он ушел с помощью кнопки «Назад». Таким образом, объект history отвечает за 2 эти кнопки, и позволять не только имитировать их нажатие, но добавлять и изменять записи в истории, перехватывать события при нажатии на эти кнопки и др.
Например: В некотором окне (вкладке) браузера пользователь изначально открыл страницу 1. Просмотрев эту страницу, пользователь нажал в ней на некоторую ссылку и перешёл на страницу 2. На второй странице пользователь снова нажал на ссылку и перешёл на страницу 3. В результате сессия истории для этого окна (вкладки) будет состоять из 3 элементов.
На текущий момент для пользователя доступна кнопка «Назад». При нажатии на эту кнопку пользователь может вернуться на страницу 2.
В этот момент времени для пользователя становится доступны кнопки «Назад» и «Вперёд». При нажатии на кнопку «Назад» пользователь может вернуться на страницу 1, а при нажатии на кнопку «Вперёд» — на страницу 3. Таким образом, пользователь с помощью кнопок «Назад» и «Вперёд» может перемещаться по истории внутри этого окна (вкладки).
Каждый элемент в сессии состоит из:
- data — это некоторые данные, которые можно связать с определённым элементом истории. В основном они используются для того чтобы восстановить состояние динамической страницы при переходе к ней с помощью кнопки «Назад» или «Вперёд». Т.е. сначала Вы сохраняете состояние страницы, а точнее динамических её блоков, которые загружаются с помощью технологии AJAX, в data . А потом, когда пользователь переходит к ней с помощью кнопки «Назад» или «Вперёд», Вы можете восстановить состояние этой страницы, а точнее этих динамических блоков (т.к. одного URL не достаточно) с помощью информации, сохранённой в data .
- title — название пункта истории. В настоящее время большинство браузеров не поддерживают возможность установления названия пункта с помощью JavaScript. Браузеры в качестве названия пункта истории используют название страницы, т.е. текст, расположенный между открывающим и закрывающим тегами HTML страницы.
- url — URL адрес страницы.
Свойства, методы и события объекта history
- Свойство history.length — возвращает количество элементов в сессии истории текущего окна (вкладки). Другими словами, данное свойство возвращает количество переходов, которые Вы можете выполнить в пределах текущего окна как вперед, так и назад. Данное свойство доступно только для чтения.
- Свойство history.state — позволяет получить данные ( data ) текущего элемента истории. Эти данные можно добавить к элементу истории с помощью методов history.pushState() и history.replaceState() .
- Метод history.go() . Он позволяет переместить пользователя на некоторое количество страниц вперёд или назад по истории. Метод history.go() имеет один обязательный параметр — это число, на которое надо переместить пользователя вверх или вниз по истории. Например, history.go(2) — осуществляет перемещения пользователя на 2 шаг назад, a history.go(-2) на 2 шага вперёд. Если в качестве параметра указать значение 0, то данный метод вызовет перезагрузку страницы. Если указать в качестве значение число, которое превышает количество шагов, которые может совершить пользователь в текущем окне, то ни чего не произойдёт.
- Метод history.back() — осуществляет перемещение пользователя на одну страницу назад по истории, т.е. он программно ‘имитирует» нажатие кнопки «Назад» в браузере. Также метод history.back() можно выполнить с помощью метода history.go(-1) .
- Метод history.forward() — осуществляет перемещение пользователя на одну страницу вперёд по истории, т.е. он программно «имитирует» нажатие кнопки «Вперёд» в браузере. Также метод history.forward() можно выполнить с помощью метода history.go(1) .
- Метод history.pushState() — позволяет добавить новую запись в сессию истории текущего окна (вкладки). Добавление записи (элемента) осуществляется в конец сессии истории.
history.pushState(data,title[,url]);
Данный метод принимает 3 параметра:
- data (обязательный параметр) — некоторые данные, которые будут связаны с этой записью в сессии истории. Если в данных нет необходимости, то используйте в качестве параметра значение null .
- title (обязательный параметр) — название записи в сессии истории.
- url (необязательный параметр) — это URL записи в сессии истории. Если URL не указать, то будет использоваться текущий адрес страницы.
history.replaceState(data,title[,url]).
onpopstate = function(event) { //код обработки события popstate //например: console.log(event.state); }
window.addEventListener ("popstate", function (e) { //код обработки события popstate });
В качестве примера рассмотрим работу с объектом history в консоли браузера:
- Откроем вкладку в браузере и введём в адресной строке http://www.yandex.ru/ и нажмём Enter .
- В этой же вкладке в адресной строке введём http://getbootstrap.com/ и нажмём опять Enter . Если посмотреть на кнопку «Назад», то он стала активной и позволяет перейти на один шаг назад, т.е. на страницу https://www.yandex.ru/ . Кроме этого можно увидеть список элементов истории, если нажать правой кнопкой мыши на кнопку «Назад».
- Откроем консоль (клавиша F12 в браузере, вкладка «Консоль») и поработаем с историей с помощью JavaScript:
- Узнаем количество элементов в истории: history.length ;
- Добавим новый элемент в историю: history.pushState(null,null,»http://getbootstrap.com/css/»);
- Перезагрузим страницу с помощью объекта history : history.go(0);
- Для примера заменим текущий элемент истории и свяжем с ним строку «Привет»: history.replaceState(«Привет»,null,»http://getbootstrap.com/javascript/»);
- Получим данные связанные с этим элементом истории: history.state;
- Перейдём на 2 шага назад по истории, т.е. на страницу http://www.yandex.ru/ : history.go(-2);