Издательский дом ООО "Гейм Лэнд"ЖУРНАЛ ХАКЕР #104, АВГУСТ 2007 г.

2.0 в пользу программера

Борис Вольфсон

Хакер, номер #104, стр. 116

(borisvolfson@gmail.com)

Технология AJAX в нашем любимом фреймворке

AJAX – эти четыре буквы стали неотделимы от идеологии Web 2.0, а библиотек для разработки AJAX-приложений уже больше нескольких сотен. Легковесная библиотека (19 килобайт!) jQuery обеспечивает широкие возможности в этой области, а набор различных плагинов делает ее подходящим инструментом для разработки современных приложений.

Ты готов?

В этой статье я расскажу, как просто создавать веб-приложения с использованием концепции AJAX. Я человек разумный, поэтому буду писать не с нуля, а в качестве фреймворка возьму jQuery. Почему именно его? Есть по крайне мере две причины. Первая – это действительно качественный фреймворк. Вторая – он не зависит от серверных технологий, поэтому можно применять либо связку LAMP (с любым языком на стороне сервера, несколько примеров есть во врезке), либо Windows-платформу. Таким образом, мы сможем сосредоточиться на клиентской части. По поводу серверной части оригинальничать не буду – возьму PHP, но специальные библиотеки для jQuery задействовать не буду, чтобы сохранилась прозрачность. В реальных проектах есть смысл использовать PQuery или писать вспомогательный код на PHP. Для самых ленивых есть вариант еще проще: использовать CMS, которая поддерживает jQuery, например Drupal.

Немного условностей

Хочу сразу пояснить, что я не буду приводить здесь полный код скриптов. Во-первых, за большое количество кода редактор обещал окунуть меня в чан с серной кислотой (обычно для нерадивых авторов используют соляную кислоту, так что я насторожен). Во-вторых, все исходники есть на диске. В начале статьи я покажу, как писать скрипты на довольно низком уровне, а затем - как работать с многочисленными плагинами. Таким образом, мы рассмотрим почти весь спектр применения jQuery в качестве клиентской AJAX-платформы.

И последнее примечание: если ты незнаком с jQuery и JavaScript, тебе может быть немного сложновато; рекомендую почитать предыдущие выпуски нашего журнала – в них много интересного, в том числе описываются основы jQuery.

Почти ассемблер

Для начала разберемся, как написать все самому с нуля, на несложном примере. Сейчас разного рода блогов и систем новостей пруд пруди. Новость (или другой материал) обычно состоит из двух частей: из анонса и основной части. Анонс, как правило, показывается на главной страничке или в общем списке новостей. Новость целиком отображается на отдельной странице. Попробуем не открывать новые странички для каждой новости, а загружать ее полный вариант вместо анонса. При этом вся работа будет происходить на одной странице. Такой подход называется single page application (SPA). Он распространен именно при использовании методологии AJAX. Плюсы и минусы обсудим позже, сейчас набросаем простенький дизайн:

Новость у нас будет состоять из двух вложенных слоев:

Исходный код одной новости

ЯЗЫК: HTML

<div class="news">

<h2>Заголовок</h2>

Текст новости

<div class="news-id">1</div>

</div>

Слой класса news играет роль контейнера, а news-id – невидимый слой с идентификатором новости. Именно его будем передавать на сервер, а он по этому числу определит, какую новость мы хотим получить полностью. С пользователем будем взаимодействовать самым простым способом: клик по заголовку вызовет загрузку полной версии новости. Заголовки можно выбрать CCS-определением «.news h2». Чтобы послать серверу запрос (в нашем случае POST-запрос), будем использовать метод $.post, которому надо передать адрес для запроса, параметры и функцию для асинхронного ответа:

Отправка POST-запроса на сервер

ЯЗЫК: JavaScript

$(document).ready(function() {

$(".news h2").click( function() {

var respondContainer = $(this).parent();

$.post("ajax.php",

{ newsId: $(this).parent().children('.news-id').text() },

function(data) { respondContainer.html(data); }

);

});

});

Рассмотрим более подробно, как происходит обмен данными между клиентом и сервером. Клиент посылает запрос с помощью $.post, передает параметры и функцию, которая будет вызвана при получении ответа. Этой функции в качестве аргумента data будет передан ответ, который сгенерирует скрипт на стороне сервера. Мы же этот ответ запишем в respondContainer – div, в котором хранится наша новость.

Если не думать о пользователе, то это все ;). Но интернет-пользователи - народ капризный и нервный. Представь, кликнул один такой по заголовку новости, а ничего не происходит. На самом деле еще как происходит: клиент серверу послал запрос и ждет не дождется ответа. Надо это пользователю и показать. jQuery предоставляет механизмы для этой нелегкой работы. Нам доступны события $(…).ajaxStart и $(…).ajaxStop, которые срабатывают при начале AJAX-запросы (запроса?) и при его остановке. Им, как и любым другим событиям, надо передать функции для вызова. Еще мы возьмем для этого простое анимированное изображение и положим его в div#loading в правый верхний угол, который по умолчанию будет невидимым. Далее пропишем действия при старте запроса и при его окончании:

Обработка начала и завершения запросов

ЯЗЫК: JavaScript

$("#loading").ajaxStart(function(){ $(this).show(); });

$("#loading").ajaxStop(function() { $(this).hide(); });

Нет более тяжелой задачи, чем отображение процесса анимации на бумаге, но Print Screen мне поможет (смотри соответствующие картинки).

Сервер должен по пришедшему айдишнику выбирать новость из базы данных, я же ограничусь схемой:

Обработка начала и завершения запросов

ЯЗЫК: PHP

<?php

$id = (int)$_POST['newsId'];

// Печатаем текст по значению newsId

// echo <<<HTML

// <div class="news">

// <h2>Заголовок</h2>

// Текст новости

// <div class="news-id">$id</div>

// </div>

// HTML;

?>

На сервере я сэкономил :). Обратить внимание стоит на первую строчку, где получается значение параметра, переданного скрипту на вход. Как и в обычном скрипте, ее надо брать из массива $_POST. Дальше выводим полный текст новости, который обычно хранится в базе данных или в файлах (у особых экстремалов). Сосредоточимся на клиенте, мне осталось поведать только про CSS. Необходимо спрятать два слоя: .news-id и #loading. Для удобства пользователя сделаем курсор мыши «перстом мудрости», когда он наводит на заголовок новости, чтобы посетитель понял, где можно (и нужно) кликать:

Фрагмент каскадных таблиц стилей для «Горячих новостей»

ЯЗЫК: CSS

h2 { cursor: pointer; }

#loading, .news-id { display: none; }

Все, с низкоуровневыми механизмами разобрались, так что самое страшное позади. Теперь будем использовать готовенькое – перейдем к обзору плагинов, которые можно использовать для написания AJAX-приложений.

Форма имеет значение

Посмотрим, какие плагины позволят облегчить наш нелегкий труд веб-разработчиков. Все адреса плагинов (а также доков и сэмплов) можно найти во врезке, к тому же я положу это богатство на диск. Что ж начнем представление! Первым номером у нас будет jQuery Form Plugin, который отвечает за передачу форм с помощью AJAX. Плагин действительно важный. Он полностью воплощает идеологию jQuery – «Write less. Do more». Обработка форм практически не отличается от обычной, а в описание формы вообще не надо вносить изменения. Достаточно написать обработчик для оправления формы и изменить код на сервере, чтобы ответ был не на новой страничке, а на той же, что и форма. Это очень удобно, например, для комментариев к статьям. Клиентский код в простейшем случае будет очень прост: надо использовать либо метод $(…).ajaxForm, либо $(…).ajaxSubmit, они имеют некоторые различия в своей работе. Хочу отметить, что плагин автоматически поддерживает работу как с JSON, так и с XML, что вкупе с вышеуказанными достоинствами делает его очень удобным не только для написания приложений, что называется, с нуля, но и для переделки под AJAX существующих сайтов.

Matrix uploaded

При программировании форм особняком стоит загрузка файлов, для которой можно использовать несколько плагинов. Я остановился на Ajax FileUpload прежде всего потому, что придется вносить минимум изменений в готовый код – как и в предыдущем случае, надо написать клиентский скрипт и подделать серверный. Плагин добавляет специальный метод $.ajaxFileUpload, которому необходимо передать следующие параметры:

Параметры метода метод $.ajaxFileUpload

url – адрес скрипта обработчика

fileElementId - input-элемент типа file, который используется для загрузки файла

dataType – формат данных, например 'json'

success – функция, которая будет вызвана при успешной передаче данных

error – функция, которая будет вызвана при ошибке

На кнопку «Загрузка» необходимо повесить обработчик события по клику «return ajaxFileUpload();». Дальше в духовку на двадцать минут - и пирог готов.

Табы - всему голова

Плагин, созданный Клаусом Хартлом для табов, - действительно мощный (очень рекомендую ознакомиться с полной демкой у него в блоге), и он поддерживает AJAX. Прежде всего опишем табы на HTML:

Список табов

ЯЗЫК: HTML

<div id="tab-container">

<ul>

<li><a href="tab_1.html">Первый</a></li>

<li><a href="tab_2.html">Второй</a></li>

<li><a href="tab_3.html">Третий</a></li>

</ul>

</div>

Обычный список, не более того. Подключаем файл с плагином… и начинаем писать код? Ничего подобного! Я бы в качестве слогана для jQuery выбрал что-то вроде: «Делай, что хочешь, одной строчкой кода!» Для того чтобы стандартный список ссылок стал табами, надо просто вызвать метод tabs у слоя, в котором он лежит:

Включаем табы

ЯЗЫК: JavaScript

$('#tab-container').tabs({ remote: true });

Истинность параметра remote как раз и означает, что содержимое табов будет загружаться с сервера. И это необязательно статические HTML-файлы, в реальных приложениях это серверные скрипты. В качестве примечания скажу, что во время написания статьи вышла свежая версия этого плагина с некоторыми усовершенствованиями, смотри сайт автора.

Ставим блок

Рассмотрим еще один вспомогательный плагин, который используется для блокировки интерфейса пользователя. Подобного рода функционал играет двоякую роль: во-первых, он может показывать пользователю, что происходит процесс передачи данных или другой процесс; во-вторых, он не дает пользователю взаимодействовать с элементами интерфейса в ненужный момент, например три раза отправить форму. В качестве дополнительной возможности с помощью этого плагина можно организовать модальные диалоговые окна. Диспозиция ясна, план готов – в бой.

Плагин BlockUI позволяет произвести все необходимые нам действия. Начнем с блокировки страницы в целом. Сценарий, при котором это необходимо делать, встречается достаточно часто. Фактически после любой отправки запроса на сервер нежелательно, чтобы пользователь взаимодействовал с веб-страничкой до получения ответа. И один из выходов - заблокировать страницу в целом, тем более что сделать это очень просто: достаточно вызвать метод $.blockUI(). Если в качестве параметра передать ему идентификатор элемента веб-страницы, например слоя, то он будет использован в качестве сообщения, иначе увидит забугорное «Please wait…» (смотри картинку).

Можно передать параметром и HTML-код, тогда будет показан он. В качестве рекомендации скажу, что лучше использовать анимированное изображение, чтобы продемонстрировать, что процесс идет.

После того как вызван метод $.blockUI(), можно писать AJAX-код, при получении ответа сервера интерфейс пользователя автоматически разблокируется. Но блокировать доступ ко всей странице в целом не всегда хорошо. Более гибкий подход предусматривает отключение только определенных элементов. Если пользователь отправляет данные с помощью формы, то и отключать стоит только ее, с остальными элементами посетитель сайта должен иметь возможность работать. BlockUI реализует такой вид блокировки при помощи метода $(…).block(). Рецепт прост: форма – 1 шт., jQuery – 1 шт., BlockUI – 1 шт., десяток элементов на форме. jQuery и BlockUI загрузить, форму положить в слой div.form, заполнить данными по вкусу, заблокировать форму $('div.form').block() до полной пересылки данных. Для активации аналогичным образом использовать метод unblock().

$(“#article”).hide()

Немало интересного удалось вставить в узкие рамки статьи, но все же мелкие подробности остались за кадром. Оправдаться могу лишь тем, что все использованные материалы (исходники, доки и прочие вкусности) будут выложены на диск. Полезно также пройтись по ссылочкам, приведенным в статье, в особенности посмотреть официальный список плагинов, который достаточно часто пополняется, в том числе и плагинами для AJAX. Кроме увеличения числа плагинов, улучшается их функционал и различные опции – стоит скачать новые версии, если они появятся.

Адреса и явки

ТИП: WWW

www.jquery.com – официальный сайт jQuery.

http://docs.jquery.com/Plugins - официальный список плагинов.

www.malsup.com/jquery/form - плагин для создания AJAX-форм.

www.phpletter.com/Demo/AjaxFileUpload-Demo - плагин для загрузки файлов.

www.stilbuero.de/jquery/tabs - плагин для создания табов.

http://malsup.com/jquery/block - плагин для блокировки интерфейса пользователя.

Дизайн 2.0 и jQuery

ТИП: Микростатья (описание дизайна)

Пока писал скрипт примера для статьи, поймал себя на мысли, что дизайн странички получился «дванольным». Действительно, ему присущи многие элементы современных веб-страниц, хотя все действия заняли от силы полчаса. Именно этим объясняется простота страницы – одна из популярных концепций современного веб-дизайна :). Обычно ситуация бывает обратная: в дизайне оказывается слишком много элементов и информационного мусора, и страницу приходится «разгружать». Достаточно крупные шрифты, в том числе и заголовка, также позволяют пользователю быстро сориентироваться, где он, и прочитать страничку в режиме сканирования, проще говоря, бегло просмотреть.

Следующие два элемента были сделаны при помощи JavaScript. Остановимся на них чуть подробнее. Во-первых, это скругленные уголки, о которых я уже писал в предыдущих статьях. Они сделаны при помощи плагина к jQuery с непредсказуемым названием corner plugin. Во-вторых, это модный эффект отражения у логотипа. Самое забавное, что отражение я сделал не в фотошопе ;). Есть достаточно неплохой скрипт reflection.js v1.6, который позволяет делать такие вещи. Надо просто добавить к изображению класс reflect. Есть реализация и для jQuery. Более гибкие настройки, например прозрачность, также реализуемы. Хочу отметить, что использование JavaScript для создания дизайна уже носит характер тенденции, а не дизайнерской прихоти.

Интеграция с PHP и Perl

ТИП: Текст с двумя заголовками и адресом. Адрес надо как-то выделить.

PQuery – интеграция с PHP

www.ngcoders.com/php/pquery-php-and-jquery

Проект PQuery – это набор PHP-библиотек для взаимодействия с jQuery. Библиотека совместима с четвертой и пятой версией PHP. Кроме исходного кода, в PQuery в дистрибутив включена документация и демонстрационные скрипты.

JQuery-1.05 – интеграция с Perl

http://search.cpan.org/~peterg/JQuery-1.05

Модуль из архива CPAN не только обеспечивает интеграцию с самой библиотекой jQuery, но и с дополнительными модулями. Имеются многочисленные демки, а вот с доками дела обстоят хуже.

LAMP – Linux/Apache/MySQL/PHP (Perl, Python, Ruby)

Выбор серверной платформы jQuery оставляет за тобой

AJAX – это не язык программирования и даже не библиотека…

…AJAX – это методология взаимодействия сервера и клиента

Содержание