Библиотека JavaScript History API: Назад в будущее.
...Так что если вы уважающий себя разработчик и желаете писать сайты по последнему слову техники, то можете смело за это браться!...Великий и могучий Интернет прочно вошел в нашу жизнь и развивается не только высокими темпами, но и часто неисповедимыми путями. Именно поэтому многие блестящие новаторские решения вынужденно дожидаются лучших времен, т.к. не могут в полной мере функционировать в неспокойном океане сети, где браузеры, воюя за превосходство либо устанавливают свои правила, либо игнорируют чужие. Не обошла такая участь и замечательную API истории HTML5. Речь в этой статье пойдет о миниатюрной и простой библиотеке History, российского программиста Дмитрия Пахтинова, которая позволяет пользоваться всеми замечательными способностями History API без опасения быть отвергнутым старыми и/или капризными браузерами.
Кратко напомню, что History API это небольшой набор методов JavaScript объекта window.history, которые позволяет управлять историей браузера, например записывать в историю требуемые адреса - history.pushState(), реагировать на события нажатия кнопок браузера "Вперед" и "Назад" - событие popstate, переписывать текущее состояние - history.replaceState() и т.д. Весь этот простой набор, однако позволяет разработчику создавать ультрасовременные динамические сайты, на которых подгрузка контента происходит без перезагрузки страницы, но при этом по доброй старой традиции меняется запись в адресной строке, заполняется история и поддерживается полноценная навигация по пройденным, а на самом деле - динамически подгруженным страницам.
Такая структура очень удобна и современна, наиболее популярные сайты (читай социальные сети, и даже не будем показывать пальцем, какие) успешно взяли ее на вооружение. Страница не мелькает и не дергается при загрузке новой информации, как это обычно происходит при перезагрузке, продолжает работать запущенный медиа-плеер, или иной процесс на странице. Повторяю, это достигается отменой перезагрузки страницы при переходе по ссылкам, и манипуляцией адресной строкой и историей из JavaScript. И все бы было чудесно, но беде случилась все та же - не поддержка History API старыми браузерами. В результате, разработчикам приходилось использовать громоздкие решения сторонних библиотек и прочие костыли. Но теперь, я с удовольствием сообщаю, что проблеме пришел конец в лице программиста devote и его библиотеки history.js.
Библиотека history.js по сути просто позволяет полноценно пользоваться способностями History API без опаски быть "непонятым" старыми браузерами и их пользователями. Так что если вы уважающий себя разработчик и желаете писать сайты по последнему слову техники, то можете смело за это браться. Библиотека history.js тестирована на таких старых браузерах как Opera 9+, FireFox3+, Internet Explorer 7+. Основные преимущества библиотеки в том, что она миниатюрна и полностью адаптивна. History.js использует стандартные методы History API, и при необходимости даже может быть легко удалена из сайта безо всякого нарушения его функциональности.
Библиотека history.js очень проста в применении.
Скачать ее последнюю версию можно по адресу http://code.spb-piksel.ru/?history.latest.zip.
Кроме того, по адресу http://history.spb-piksel.ru/ можно наглядно изучить на примере демо сайта как работает history.js.
Общее хранилище разработок автора можно найти тут https://github.com/devote.
Здесь я кратко опишу лишь основные моменты библиотеки history.js...
Подключение библиотеки может сопровождаться внесением трех параметров:
Первый параметр необходим, если сайт помещен не в корневую директорию домена, а в одну из внутренних папок, тогда часть пути указанная в basepath будет дописываться в начало всех ссылок, обеспечивая корректные переходы Вторые два параметра служат для придания эстетической красоты ссылкам: redirect - убирает из ссылок символ якоря #, который необходим для совместимости со старыми браузерами. Дело в том, что в старых браузерах невозможно поменять ссылку в адресной строке не перезагрузив при этом страницу, и чтобы обойти это досадное свойство стали использовать метод якоря, который по спецификации ссылается на некое место текущей страницы, и не допускает обновления. А вот новые браузеры, знающие, что такое history.pushState(), не нуждаются в этом костыле, и параметр redirect умеет "очищать" ссылку для них, но добавлять символ # в адрес тем, кому history.pushState() не ведом. type - также служит для причесывания вида ссылок в строке, например чтобы якорь начинался со знака слеш.
Параметры basepath, redirect и type можно комбинировать при вызове:
history-1.2.6.min.js?type=/&redirect=false&basepath=/pathtosite/ // порядок опций не имеет значение.
Далее, я не стану вдаваться в подробности динамической загрузки контента, т.к. методы AJAX выходят далеко за рамки данной статьи. Основная идея состоит в том, чтобы при клике по ссылке, отменить перезагрузку ( return false), подгрузить нужный контент (ajax) и записать путь в историю ( pushState ). Но прежде всего, нужно повесить обработчик на событие popstate, реагирующее на нажатие кнопок браузера "Вперед" и "Назад". Так разработчик описывает эту процедуру:
Использование события popstate на чистом JS:
window[ window.addEventListener ? 'addEventListener' : 'attachEvent' ] ( 'popstate', function( event ) { // получение location из объекта event var loc = event.location || document.location; alert( "return to: " + loc ); }, false);
Или использование события popstate в связке jQuery:
$( window ).bind( 'popstate', function( event ) { // jQuery оригинальное событие хранит в свойстве originalEvent var loc = event.location || ( event.originalEvent && event.originalEvent.location ) || document.location; alert( "return to: " + loc ); });
Обратите внимание, здесь используется event.location именно для поддержки старых браузеров. Далее иллюстрацией работы послужит сам файл http://history.spb-piksel.ru/js/main.php с демо сайта. Основные моменты: повесим на клик по ссылкам нужный обработчик, используя например jQuery:
$("#main_content a.ajax").click( actionAnchors );
Опишем функцию:
function actionAnchors( e ) { // подгружаем нужный контент this.href && loadContent( this.href, true ); return false; }
и далее создадим функцию динамической загрузки, где помимо загрузки контента, в зависимости от параметра push записываем историю:
function loadContent( url, push ) { // вызываем ajax, подгружаем контент... ... // if ( push ) { // записываем историю и заменяем ссылку в браузере history.pushState( null, null, url ); } }
И конечно, не забываем про наш собственный обработчик popstate, который будет вызывать loadContent без параметра push, т.е. в историю ничего не вносить:
$( window ).bind( 'popstate', function( e ){ var loc = e.location || ( e.originalEvent && e.originalEvent.location )|| document.location; // подгружаем нужный контент loadContent( loc.href ); });
На этом статья заканчивается, а написание сайтов продолжается.
Как любит говаривать автор библиотеки History.js : "Пользуйтесь на здоровье!".