Большинство веб-разработчиков ограничивают себя в использовании аякса, потому что он, как известно, обладает некоторыми распространенными недостатками: 1. Неиндексируемость динамически загружаемого содержимого поисковиками; 2. Невозможность работать с URL (к примеру, добавлять в закладки динамически загруженный материал); 3. Динамически создаваемые страницы не регистрируются в истории браузера, поэтому невозможно использовать клавиши «назад» и «вперед»; Но, на другой стороне весов имеются неопровержимые преимущества AJAX: 1. Экономия трафика; 2. Уменьшение нагрузки на сервер; 3. Ускоренная работа веб-приложения (это результат первых двух пунктов). В этом уроке мы расскажем, как преодолеть минусы и полноценно пользоваться плюсами AJAX. Идеи 1. Все страницы сайта получаем через AJAX, т. е. обновляем только заголовок и содержимое страницы. Это увеличивает скорость работы сайта и снижает трафик между сервером и браузером. 2. У каждой «аяксовой» страницы свой адрес. Например, вы кидаете другу ссылку в аське на такую страницу и он видит именно то, что нужно. Или человек приходит по ссылке на какую-то страницу (скажем, из поисковика) и тоже видит нужную страницу. 3. Понятная навигация — страницы сайта не ссылаются сами на себя. В нашем случаем мы будем просто выделять ссылки на текущую страницу. 4. Рабочие кнопки «назад» и «вперед». Чтобы пользователь работал с нашим сайтом в привычной ему форме. 5.Работа сайта без Javascript. Содержимое сайта будет индексироваться поисковиками и приверженцы текстовых браузеров тоже не останутся в обиде. Серверная часть Для начала нам нужен обычный сайт. Кроме того, у нас должна быть возможность получать одну и ту же страницу в форматах HTML (полный код страницы) и XML (только заголовок и содержимое страницы). При этом будет удобно, если html и xml версии будут различаться только одним параметром в адресе. Например, так: * HTML версия страницы — /page1/page 1-1.html; * XML версия — /page1/page 1-1.html?ajax=yes. Мы сделали это на PHP, вы же можете выбрать любой другой серверный язык программирования. Клиентская часть Для простоты работы возьмем библиотеку jQuery (с ее помощью будем реализовывать AJAX). Для работы с историей браузера понадобиться библиотека unFocus History. Для начала нам нужно переписать адреса у ссылок и на событие click привязать выполнение AJAX-запроса, отметку ссылок с тем же адресом, что и у текущей, и добавление этого клика в историю посещений. Обратите внимание, что мы не будем переписывать следующие типы ссылок: * внешние ссылки, т. е. ссылки на страницы других сайтов; * ссылки на картинки, архивы и прочие файлы (расширения таких файлов указываем в переменной forbiddenTypes); * ссылки с заранее указанным классом (forbiddenClass) — если внутри сайта есть страницы, которые необходимо грузить целиком. Code function setupNewLinks(obj) { var links = obj.getElementsByTagName("a"); // все ссылки внутри объекта obj // перебираем ссылки for (i = 0; i < links.length; i ++) { // проверяем, можно ли переписывать адрес текущей ссылки //(проверка по имени класса, расширению и "внешности" ссылки :-) // если можно, то переписываем tmp = links[i].href; tmp = tmp.replace("http://"+site, ""); indexOfDot = 0; if(tmp.lastIndexOf(".") > 0) indexOfDot = tmp.lastIndexOf("."); if(forbiddenTypes.match(tmp.substring(indexOfDot)) == null && tmp.substring(0, 7) != "http://" && links[i].className != forbiddenClass) { // прописываем, что происходит при клике на ссылку $(links[i]).bind("click", function() { markLinksWithHref(this.href); historyVar.getNewHistoryState(this.href.replace("http://"+site+"/#", "")); this.className = "curPage"; }); // заменяем адрес links[i].href = "#" + tmp; } } } Параметром функции указываем объект страницы, внутри которого надо искать ссылки.Вначале указываем весь документ (setupNewLinks(document)), при каждом обновлении контента — только этот контент (setupNewLinks(document.getElementById(’’content’’))). Сейчас при клике на ссылку ее класс меняется на curPage. Но нам нужно отметить все такие ссылки внутри страницы. Для этого используем вот такую функцию. Ее аргумент — адрес текущей ссылки. Code // с помощью этой функции мы отмечаем все ссылки // с одинаковым значением href function markLinksWithHref(linkHref) { var links = document.getElementsByTagName("a"); if(navigator.appName == 'Microsoft Internet Explorer') linkHref = linkHref.replace("http://"+site+"/", ""); for (i = 0; i < links.length; i ++) { if(links[i].href == linkHref || links[i].href == linkHref+"/") links[i].className = "curPage"; else links[i].className = ""; } } Мы получили данные в формате XML и теперь нам нужно их распарсить и заменить заголовок и содержание текущей страницы. Аргументом функции будет полученный XML. Code function parseGetData(data) { //получаем заголовок и содержание страницы из XML title = data.getElementsByTagName('title'); cnt = data.getElementsByTagName('content'); //вставляем это в нашу страницу $('#content').html(cnt[0].firstChild.nodeValue); document.title = title[0].firstChild.nodeValue; // обновляем ссылки внутри страницы setupNewLinks(document.getElementById('content')); markLinksWithHref(window.location.href); } Итак,мы реализовали пункты 1 и 3. Сделаем пункт 2. При каждой загрузке страницы (или клике на кнопки «назад» или «вперед») мы будем проверять адрес и показывать пользователю нужную ему страницу. Заметим, что проверка при первой загрузке и переходе из истории немного отличаются. Code function checkAnchorOnload() { // определяем полный путь и якорь страницы var urlPathName = location.pathname; var urlAnchor = location.hash; // проверяем адрес, если пользователь первый раз //вошел на сайт. Если в адресе есть якорь, то // подгружаем страницу if(start == 'yes') { if(urlPathName != "/") { location.href = "http://"+site+"/#"+urlPathName; } else if(urlAnchor != "" && urlAnchor.indexOf("#/") != -1) { getDataAjax(urlAnchor.replace("#", "")); } } // примерно такая же проверка, но только при нажатии // "назад" или "вперед" в браузере else if(start == '') { if(urlPathName == "/") { if(urlAnchor == "" || (urlAnchor == "#" && navigator.appName == 'Microsoft Internet Explorer')) { getDataAjax("http://"+site+"/"); } else if(urlAnchor.indexOf("#/") != -1) { getDataAjax(urlAnchor.replace("#/", "")); } } } } Рассмотрим функцию, которая будет «слушать» изменение истории и реагировать на нажатия кнопок «назад» и «вперед». Code function historyHandler() { var stateVar = "nothin'", displayDiv = document.getElementById("content"); this.getNewHistoryState = function(currentState) { var newVal = currentState; unFocus.History.addHistory(newVal); }; this.historyListener = function(historyHash) { stateVar = historyHash; // при каждом изменении истории мы будем // выдавать соответствующий контент checkAnchorOnload(); }; unFocus.History.addEventListener('historyChange', this.historyListener); this.historyListener(unFocus.History.getCurrent()); }; var historyVar; Мы написали все необходимые функции, осталось только «привязать» их к странице. Code function init() { setupNewLinks(document); // переписываем адреса ссылок historyVar = new historyHandler(); // запоминаем историю start = ''; } Лучше всего вызывать эту функцию либо при загрузке DOM, либо в конце самого документа. В итоге у нас получился вот такой сайт. Архив со скриптами урока ZIP архив, 29КБ Автор статьи: Павел Марковнин
|