Библиотека для работы HTML5 History API
Изначально этот проект был задуман добавить поддержку HTML5 History API в старые HTML4 браузеры. Первые версии библиотеки были нацелены именно на эти потребности, но с учетом прошедшего времени и пожеланий многоуважаемых разработчиков использующих эту библиотеку, она выросла до уровня того, что выполняет некие промежуточные действия по добавлению/исправлению того функционала что описаны в спецификациях по интерфейсу History.
На сегодняшний день библиотеку я могу смело назвать, на мой взгляд, полноценно законченной. Конечно же, ошибкам в работе библиотеки думаю, место будет, тестировалась библиотека мною в разных условиях и браузерах, но как вы понимаете, все не уловишь, да что-то упустишь. И так давайте приступим к описанию возможностей и тонкостей библиотеки.
Использование.
Использование библиотеки очень простое, она максимально пытается придерживаться официальной спецификации по интерфейсу History.
Приведу небольшой пример:
<!DOCTYPE html>
<html>
<head>
<script type="text/javascript" src="history.js"></script>
<script type="text/javascript">
window.onload = function() {
// просто функция добавляет DIV с нужным нам текстом
function appendText( text ) {
var div = document.createElement( "div" );
div.innerHTML = text;
document.body.appendChild( div );
}
// функция для ссылок обрабатывается при клике на ссылку
function handlerAnchors() {
// заполним хранилище чем нибудь
var state = {
title: this.getAttribute( "title" ),
url: this.getAttribute( "href", 2 ) // двоечка нужна для ИЕ6-7
}
// заносим ссылку в историю
history.pushState( state, state.title, state.url );
// тут можете вызвать подгруздку данных и т.п.
// ...
appendText( '<b>Вы перешли по ссылке:</b> ' +
'<span style="color: green;">' + state.url + '</span>' );
// не даем выполнить действие по умолчанию
return false;
}
// ищем все ссылки
var anchors = document.getElementsByTagName( 'a' );
// вешаем события на все ссылки в нашем документе
for( var i = 0; i < anchors.length; i++ ) {
anchors[ i ].onclick = handlerAnchors;
}
// вешаем событие на popstate которое срабатывает
// при нажатии back/forward в браузере
window.onpopstate = function( e ) {
// просто сообщение
appendText( '<b>Вы вернулись на страницу:</b> ' +
'<span style="color: green;">' + history.location + '</span>' +
'<br/><b>state:</b> <span style="color: green;">' +
JSON.stringify( history.state ) + '</span><br/><br/>' );
// тут можете вызвать подгруздку данных и т.п.
// ...
}
}
</script>
</head>
<body>
<h1>Переходите по ссылкам, а затем жмите в браузере кнопки back/forward</h1>
<a href="/mylink.html" title="Заголовок связанный с ссылкой My Link">My Link</a>
<a href="/otherlink.html" title="Заголовок связанный с ссылкой Other Link">Other Link</a>
</body>
</html>
Как видите, ничего сложного в использовании этой библиотеки нет, из примера выше вы, наверное, заметили, что разница/отличия использования методов описанных в спецификации по интерфейсу History практически отсутствуют. Имеется лишь одна небольшая разница в том, что получение текущей ссылки при срабатывании события
popstate
, мы получаем из объекта history.location
.Как это работает.
В браузерах HTML5 она выполняет лишь роль исправления багов/ошибок при работе с историей. А ссылки имеют нормальный приятный вид, без использования каких либо hash-fallback.
В браузерах HTML4, конечно же, используется hash-fallback, ибо другого варианта для таких браузеров, конечно же, нет. Но для разработчика внутри JavaScript-кода это не будет являться каким-то недугом, потому как ссылки будут иметь тот вид, что изначально задуманы. И вам не нужно где либо, прописывать hash-ссылки и/или соблюдать правила для поисковиков, что бы те в свою очередь нормально индексировали сайт. Ведь ссылки будут нормального вида, а значит поисковый робот, спокойно перейдет по нужной ссылке.
Функционал библиотеки.
Библиотека имеет небольшие тонкости при работе с ней. Как мы уже заметили, у библиотеки есть собственный объект
history.location
, он ничем не отличается от известного объекта window.location
. То есть одним словом это и есть ссылка на объект window.location
за исключением того что в браузерах HTML4 он перехватывает getters/setters у оригинального объекта, делает нужные модификации и возвращает результат.Способ работы с
history.location
ничем не ограничен, вы так же можете его назначать, получать, обращаться к его свойствам и т.д.К примеру, это выглядит так:
history.location = "http://yandex.ru/"; // произойдет переход на страницу Яндекса.
history.location.hash = "#newhash"; // просто сменим hash на странице.
// и так далее по всем свойствам, описанным
// в спецификации по интерфейсу Location
Следующая тонкость библиотеки это его настройка под ваши нужды. Библиотека не имеет каких-то объектов для настройки, а получает их из параметра GET при подключении библиотеки через HTML-элемент
script
, то есть считывает ссылку при подключении скрипта к сайту.Выгладит это примерно так:
<script type="text/javascript" src="history.js?type=/&redirect=true&basepath=/pathtosite/"></script>
Подключая библиотеку к сайту, вы можете, заранее ей указать какие действия требуются от нее. Библиотека имеет всего три параметра, сейчас я вам опишу их действия и необходимость.
Параметр: type
Особой роли не играет, он нужен для украшения ссылки в браузерах HTML4. В этом параметре вы можете указать совершенно любую строку/символ, который будет добавлен после знака # (hash), тем самым вы просто украсите ссылку нужным знаком/текстом. К примеру, если я задам этому параметру текст: «HelloWorld/», то ссылки будут иметь эту подстроку. Допустим кликнув по ссылке http://somesite.com/folder/page.html мы получим ссылку вида: http://somesite.com/#HelloWorld/folder/page.html. Вы можете поэкспериментировать с этим параметром. По умолчанию в библиотеке этот параметр имеет подстроку "/" (слеш).
Параметр: basepath
Один из важных параметров, именно по этому параметру библиотека формирует ссылку для объекта
history.location
. Он указывает, где находиться корень сайта, обычно сайты лежат прямо в корне домена, но иногда бывает нужно сайт положить в иную папку от основного домена. Для этого и был добавлен этот параметр, что бы сайты, находящиеся вне корня могли полноценно работать в браузерах HTML4.Параметр: redirect
Этот параметр отвечает за переадресацию сайта при переходе по ссылке, скопированной в браузере HTML4 в браузер HTML5. Она просто перенаправляет пользователя перешедшего по ссылке вида: http://somesite.com/#/folder/page.html на ссылку вида http://somesite.com/folder/page.html и наоборот, если пользователь перешел по ссылке из браузера HTML5 в браузер HTML4. Важно помнить, что этот параметр тесно связан с параметром basepath, так как именно по этому параметру он делает выводы, куда перенаправить пользователя.
Заключение.
В заключении хочу добавить, что иногда порой нужно узнать в каком браузере мы находимся, в браузере HTML4 или в браузере HTML5. Для этих целей я добавил свойство emulate в объект
window.history
указывающее на то происходит эмуляция или нет. Если это свойство имеет значение true, значит, мы находимся в браузере HTML4 и работаем с hash-ссылками, в противном случае иное.Так же добавлю, что в браузерах HTML5 библиотека исправляет баги/недоделки интерфейса History и все что с ним связано. К примеру, в Safari добавляет объект state в интерфейс History, в браузерах Safari и Chrome убирает initial state (срабатывание события
popstate
при первой загрузке документа).Важно помнить, библиотека не делает того чего не описано в спецификации, она оперирует лишь по официальному документу. Библиотеку стоит подключать на странице самой первой, так как она перегружает некоторые методы/свойства, и любое обращение к методам/свойствам, связанным с ней, она сразу же перехватывает. Поэтому стоит ее подключать раньше других библиотек/скриптов.
Библиотека работает с совершенно любыми фреймворками, и не использует их для своих целей.
Библиотека была протестирована в браузерах:
IE 6+
FireFox 3+
Opera 11+
Opera Mobile 11+
Chrome 17+
Safari 5+
Если у вас есть возможность проверить в других браузерах или версиях и вам не составит труда мне отписаться, то я буду очень вам признателен.
Все пожелания, вопросы, отчеты о багах и т.д. вы можете мне посылать на почту, указанную на ГитХабе или написать в разделе Issues на ГитХабе.
Скачать и посмотреть данную библиотеку вы можете на GitHub: https://github.com/devote/HTML5-History-API
Так же можете посмотреть работоспособность библиотеки на моем, к сожалению не доделанном сайте: http://history.spb-piksel.ru/. Сам сайт не доделан, но работоспособность библиотеки вы можете на нем посмотреть.
UPD(12.09.2012): Важно! Мне часто стали писать/сообщать о неработоспособности библиотеки в ИЕ9. Проблема связана с тем, что ИЕ9 капризный браузер и придирается ко всем мелочам. Как выяснилось, многие разработчики что используют скрипты взятые с GitHub сталкиваются с проблемами их неработоспособности, потому что ИЕ9 при подключении скриптов ожидает получить заголовок application/javascript, но GitHub возвращает заголовок text/plain. Поэтому подключать скрипты напрямую с GitHub не рекомендуется. Скачайте скрипт к себе на хост и используйте.