[116]
01 Янв 2012, 16:55

Смена адреса страницы без её перезагрузки или HTML5 History API

Всем привет!

На днях проводил эксперименты с загрузкой всех страниц сайта с помощью технологии AJAX и возможностью обращения к такми страницам напрямую с помощью #hash. Вообщем хоть это и кроссбраузерный способ, он мне показался не слишком удобным, да ещё и громоздким. И тут я вспомнил, что в HTML5 можно управлять историей браузера. «Вот он — веб-сайт моей мечты!» подумал я.

И так, в данной статье я приведу элементарнейший пример, как можно организовать обновление адресной строки браузера с адресом страницы сайта без перезагрузки самой страницы.

Сразу приведу код страницы с примером.

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=windows-1251">
<title>Главная страница</title>
</head>
<body>

<a href="/one/" onclick="followLink(event, this)">первая страница</a> | 
<a href="/two/" onclick="followLink(event, this)">вторая страница</a> | 
<a href="/three/" onclick="followLink(event, this)">третья страница</a>

<script type="text/javascript">

function followLink(event, link)
{
	var nameLink = link.innerHTML;
	uploadContent(link.href);
	history.pushState({title:nameLink, href:link.href}, null, link.href);
	updateTitle(nameLink);
	event.preventDefault();
}

function updateTitle(title)
{
	var elm = document.getElementsByTagName('title')[0];
	elm.innerHTML = title;
}

function uploadContent(link)
{
	//тут реализуем загрузку части страницы с помощью AJAX
}

window.addEventListener("popstate", function(e) {
	uploadContent(e.state.href);									 
	updateTitle(e.state.title);
}, false );

</script>

</body>
</html>

Вот всё что нам понадобиться. Теперь подробнее о схеме работы.

На странице имеется 3 ссылки, на каждой из которой установлено событие onclick, которое вызывает функцию followLink(event, this). Функция принимает два параметра, событие и ссылку на элемент.

Главная особенность функции это вызов метода pushState:

history.pushState({title:nameLink, href:link.href}, null, link.href);

Таким образом мы обновляем URL в адресной строке браузера без перезагрузки самой страницы.

Метод history.pushState принимает 3 параметра:

  1. state — структура данных фармата JSON. Он передается обработчику событий popstate, о котором мы поговорим позже.
  2. title — строка определяющая заголовок страницы. Этот параметр в настоящее время не используется основными браузерами. Так что заголовок будем менять по другому.
  3. url — это URL, который должен отображаться в адресной строке браузера.

Если рассказать коротко, то функция followLink срабатывает при клике по ссылке, вызывает функцию uploadContent которая должна получить кусок страницы от сервера и установить его на нужное место. Потом функция должна поменять адрес страницы в адресной строке браузера и заголовок страницы вызвав функцию updateTitle.

Казалось бы и всё что нам нужно. Адрес меняется, заголовок тоже. Но если в браузере нажать кнопку «Назад», то перехода на предыдущую страницу происходить не будет.

Когда пользователь переходит на новую страницу с полным её обновлением, то браузер запоминает новый URL в истории браузера. Если пользователь нажимает кнопку «Назад», то браузер сдвигает одну страницу в истории и возвращает её пользователю. Но теперь, когда полной перезагрузки страницы не происходит, то и никакого сохранения в истории не происходит тоже.

Для перехода к предыдущей странице существует событии popstate. Это событие срабатывает всякий раз когда пользователь нажимает кнопку «Назад». Значит нам нужно только передать функции uploadContent старый адрес страницы и вернуть старый заголовок.

Объект event, который передается в обработчик события popstate имеет свойство state, которое содержит данные, которые мы передали в качестве первого аргумента функции pushState. Из этого свойства мы можем узнать предыдущий адрес страницы и её заголовок.

Также обратите внимание, что если будет нажата кнопка «Обновления страницы» или попытка обратиться к этой странице напрямую, ничего не произойдет. Так что в движке сайта должен быть предусмотрен механизм загрузки страниц сайта и с полной перезагрузкой.

History API поддерживают следующие браузеры:

  1. Firefox 4.0+
  2. Safari 5.0+
  3. Chrome 8.0+
  4. Opera 11.10+
  5. IE 9.0

#javascript, #html5

Комментарии (5)
zzoll
06 Янв 2012, 18:05
#

А я ломал голову, как они так Вконтакте делают. Вот оно что.

systes
06 Янв 2012, 20:51
#

А я делаю сейчас такие адреса:

mysite.ru/#/model/param/

Хорошо смотрится, хотя ваше решение очень хорошо.

impulse
12 Апр 2013, 23:51
#

Извините а можете все подробнее расписать для чайников??? я просто AJAX не совсем понимаю(((

Valentina
10 Янв 2014, 18:03
#

Здравствуйте, у меня в консоле появляется ошибка Uncaught TypeError: Cannot read property 'href' of null в window.addEventListener не могу понять в чем причина.

DevilST
13 Фев 2014, 18:03
#
function uploadContent(link)
{
А примерно какие команды нужны вписывать в эту область
}

а то я перепробовал $('.content'),
var elm = document.getElementsByClassName('content')[0];
elm.innerHTML = body;
но ни чего не получилось

Добавить комментарий

Войдите, чтобы написать о чем-нибудь...
Вход Регистрация
Web.onRails
Здесь вы можете спросить или написать обо всём, что касается Веб-разработки.
написать о чем-нибудь...
Метки: