» Форма входа

»Мoy-weB ver.4.1

» Статистика

Главная » 2009 » Май » 2 » Хороший AJAX

Хороший AJAX
02.Май.2009 | 21:09:21
Большинство веб-разработчиков ограничивают себя в использовании аякса, потому что он, как известно, обладает некоторыми распространенными недостатками:

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КБ

Автор статьи: Павел Марковнин

Категория: JAVA скрипты | Просмотров: 638 | Добавил: CorsaR
Добавлять комментарии могут только зарегистрированные пользователи.
[ Регистрация | Вход ]