До появления HTML5 единственное, что мы не могли контролировать и управлять (без перезагрузки контента или хаков с location.hash) — это история одного таба. С появлением HTML5 history API все изменилось — теперь мы можем гулять по истории (раньше тоже могли), добавлять элементы в историю, реагировать на переходы по истории и другие полезности. В этой статье мы рассмотрим HTML5 History API и напишем простой пример, иллюстрирующий его возможности.
History API опирается на один DOM интерфейс — объект History. Каждый таб имеет уникальный объект History, который находится в
Основные методы объекта History:
Для перехода на 2 шага назад по истории можно использовать:
Для добавления элементов истории мы можем использовать
Для изменения записи истории мы можем использовать
Теперь мы знаем основы, давайте посмотрим на живой пример. Мы будем делать веб файловый менеджер, который позволит вам найти URI выбранного изображения(посмотрите то, что получится в конце). Файловый менеджер использует простую файловую структуру, написанную на JavaScript. Когда вы выбираете файл или папку картинка динамически обновляется.
Мы используем
Чтобы все работало быстро мы подгружаем все картинки и обновляем атрибут
HTML5 history приходит на помощь! Каждый раз когда мы выбираем файл создается новая запись истории и
У нас есть 2 дива. Один содержит структуру папок, другой содержит текущую картинку. Все приложение управляется с помощью JavaScript. В будут освещены только самые важные моменты. Исходный код примера очень короткий (порядка 80 строк) посмотрите его после прочтения всей статьи.
Метод
Объект
Мы навешиваем обработчик на событие
— Если это папка мы открываем или закрываем её
— Если это картина, то мы показываем её и добавляем элемент истории
Метод, который изменяет содержимое картинки и обновляет её подпись очень прост:
Мы получили простое приложение, демонстрирующее возможности обновленного интерфейса объекта
Firefox 4+
Safari 5+
Chrome 10+
Opera 11.5+
iOS Safari 4.2+
Android 2.2+
IE ???
Список браузеров, поддерживающих history API
1. Facebook
2. Github — навигация по дереву проекта
3. ???
1. Manipulating History for Fun & Profit
2. WHATWG HTML5 history API
3. W3C history API Spec
4. MDC Manipulating the browser history
5. History.js — скрипт эмулирует HTML5 history API(location.hash magic) в тех браузерх, которые его не поддерживают
Основные понятия и синтаксис
History API опирается на один DOM интерфейс — объект History. Каждый таб имеет уникальный объект History, который находится в
window.history
. History имеет несколько методов, событий и свойств, которыми мы можем управлять из JavaScript. Каждая страница таба(Document object) представляет собой объект коллекции History. Каждый элемент истории состоит из URL и/или объекта состояния (state object), может иметь заголовок (title), Document object, данные форм, позиция скролла и другую информацию, связанную со страницей. Основные методы объекта History:
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])
: Обновляет текущий элемент истории
Для перехода на 2 шага назад по истории можно использовать:
history.go(-2)
Для добавления элементов истории мы можем использовать
history.pushState
:history.pushState({foo: 'bar'}, 'Title', '/baz.html')
Для изменения записи истории мы можем использовать
history.replaceState
:history.replaceState({foo: 'bat'}, 'New Title')
Живой пример
Теперь мы знаем основы, давайте посмотрим на живой пример. Мы будем делать веб файловый менеджер, который позволит вам найти URI выбранного изображения(посмотрите то, что получится в конце). Файловый менеджер использует простую файловую структуру, написанную на JavaScript. Когда вы выбираете файл или папку картинка динамически обновляется.
Мы используем
data-*
атрибуты для хранения заголовка каждой картинки и используем свойство dataset для получения этого свойства:<li class="photo">
<a href="crab2.png" data-note="Grey crab!">crab2.png</a>
</li>
Чтобы все работало быстро мы подгружаем все картинки и обновляем атрибут
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({note: note, path:f.textContent}, '', f.textContent);
}
}, false);
Метод, который изменяет содержимое картинки и обновляет её подпись очень прост:
loadImage: function(path, note){
img.src = path;
h2.textContent = 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. ???
Почитать
1. Manipulating History for Fun & Profit
2. WHATWG HTML5 history API
3. W3C history API Spec
4. MDC Manipulating the browser history
5. History.js — скрипт эмулирует HTML5 history API(location.hash magic) в тех браузерх, которые его не поддерживают