VDS за 300р от нашего партнера SpaceWeb
[125]
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.01.2012 18:05

А я ломал голову, как они так Вконтакте делают. Вот оно что.
+3
systes 06.01.2012 20:51

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

mysite.ru/#/model/param/

Хорошо смотрится, хотя ваше решение очень хорошо.
+1
impulse 12.04.2013 23:51

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

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

function uploadContent(link)
{
А примерно какие команды нужны вписывать в эту область
}

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

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

Войдите, чтобы написать о чем-нибудь...
Вход Регистрация
Web.onRails
Найди ответ на любой вопрос по Веб-разработке!
задать вопрос...
Вы можете разместить Рекламный пост самостоятельно, либо отправив контент по адресу admin@webonrails.ru→ Оплата здесь ←Неоплаченные посты удаляются.
Метки:
Лучшее
[52]
16 Окт 2011, 15:38
Вывести все элементы POST
[просмотров 36580]
[100]
19 Дек 2014, 16:16
User-agent для Internet Explorer 11
[просмотров 36054]
[1]
15 Апр 2021, 08:29
Переполнение памяти Nuxt.js
[просмотров 34850]
[74]
31 мая 2011, 11:48
Python проверка существования переменной
[просмотров 14502]
[125]
21 Июл 2011, 14:04
Python Imaging Library (PIL)
[просмотров 11807]
[4]
10 Окт 2018, 15:33
Как запретить просмотр сайта по IP?
[просмотров 10852]
[50]
31 Дек 2011, 14:57
Cron запускать раз в неделю
[просмотров 8951]

Вести с Хабра