Сравниваем инфраструктуры для разработки на JavaScript

Обзор инфраструктур для разработки на JavaScript

В этой статье мы узнаем, как инфраструктуры JavaScript облегчают и ускоряют разработку сайтов и Web-приложений с высокой интерактивностью и скоростью работы.

Джо Леннон, разработчик ПО, Независимый разработчик

Джо Леннон - 24-летний разработчик ПО из города Корк, Ирландия. Джон является автором вскоре выходящей в издательстве Apress книги Beginning CouchDB, а также нескольких технических статей и руководств на IBM developerWorks. В свободное время Джо любит играть в футбол, возиться с гаджетами и ставить игровые рекорды на своей Xbox 360.



08.12.2010

Введение

JavaScript - это объектно-ориентированный язык сценариев, который уже давно используется в разработке Web-приложений для создания выполняемых на клиенте сценариев. JavaScript позволяет Web-разработчикам программным образом работать с находящимися на Web-странице объектами, предоставляя платформу для манипулирования этими объектами на лету. Когда JavaScript только появился, он, как правило, использовался для реализации довольно тривиальной функциональности, такой как часы на Web-странице или прокрутка текста в строке состояния браузера. Другой типичной функциональностью были "наводящиеся ссылки", в которых изображение или цвет текста ссылки менялись при наведении курсора мыши. Однако в последнее время JavaScript эволюционировал и стал гораздо более полезным, а концепция асинхронного JavaScript в сочетании с XML - Ajax (Asynchronous JavaScript and XML) - вывела возможности реализации интерактивности Web-приложений на новый уровень. До Ajax любая обработка данных на сервере или операция с базой данных требовала обновления всей страницы целиком или отображения новой страницы. Такой подход не только был медленным и недружелюбным по отношению к пользователю, но и тратил впустую пропускную способность сетевого канала и ресурсы компьютера.

Ajax расшифровывается как Asynchronous JavaScript and XML, хотя сейчас запросы Ajax могут возвращать данные и в отличных от XML форматах, например, JSON (JavaScript Object Notation). Ajax позволяет из кода JavaScript асинхронно посылать HTTP-запросы на Web-сервер, а затем отображать его результат без обновления существующей страницы или отрисовки новой. Чтобы отразить изменения или данные, возвращенные в HTTP-ответе, изменяют лишь часть Web-страницы посредством манипуляций с моделью DOM (Document Object Model - объектная модель документа).


Что такое инфраструктура JavaScript?

JavaScript сам по себе очень мощный язык, и, вообще говоря, на нем можно создавать приложения с насыщенным пользовательским интерфейсом без помощи дополнительных инфраструктур. Однако использовать JavaScript напрямую – работа не из легких. В первую очередь это связано со сложностями, возникающими при попытках обеспечить работу приложения в различных Web-браузерах. Как и в случае HTML и CSS, каждый браузер имеет свою собственную реализацию JavaScript, поэтому обеспечение кросс-браузерной совместимости приложения может стать настоящим кошмаром.

Инфраструктура или библиотека JavaScript представляет собой набор утилит и функций, которые существенно облегчают создание кода JavaScript, совместимого с множеством браузеров. Каждая библиотека активно тестируется на последних версиях многих современных Web-браузеров, поэтому вы, используя какую-либо из этих инфраструктур, можете быть уверены, что ваше приложение будет работать схожим образом на различных браузерах и платформах.

Помимо обеспечения кросс-браузерной совместимости, инфраструктуры JavaScript облегчают написание кода для извлечения, навигации и манипуляции с DOM-элементами. Они не только предоставляют простые функции для получения ссылок на элементы модели DOM, но и позволяют записывать цепочки вызовов функций обхода дерева DOM для поиска на любой глубине предков, потомков или братьев элемента. Наконец, инфраструктуры предоставляют ряд функций, облегчающих манипулирование этими объектами, позволяя изменять, добавлять или удалять непосредственно содержимое элементов, или манипулировать стилями CSS для изменения внешнего вида элемента.

Другой важной функциональностью инфраструктур JavaScript является улучшенная поддержка обработки событий. Кросс-браузерная обработка событий может оказаться кошмаром в связи с различными реализациями событий в разных браузерах, поэтому инфраструктуры JavaScript обычно оборачивают события браузера в набор функций, которые корректно работают в различных браузерах. Некоторые инфраструктуры также предоставляют набор стандартизованных кодов клавиш, которые представляют связанные с клавиатурой события (такие как нажатие клавиш Escape, Return, клавиш курсора и т.д.).

Вся эта функциональность очень важна, но, пожалуй, главным фактором недавнего роста популярности инфраструктур JavaScript стала поддержка Ajax. Как и другие аспекты JavaScript, технология Ajax в каждом Web-браузере реализована особенным образом, что делает утомительной работу по поддержке совместимости приложения с разными браузерами. Почти все инфраструктуры JavaScript включают в себя какую-либо библиотеку, поддерживающую Ajax, которая обычно предоставляет объекты для работы с запросами и ответами Ajax, вспомогательные функции для анализа ответов, обновления DOM-элементов и периодического опроса сервера.


Типичная функциональность инфраструктур JavaScript

Рассмотрим полезную функциональность, типичную для большинства инфраструктур JavaScript. Вот эта функциональность:

  • Селекторы
  • Обход дерева DOM
  • Манипуляция моделью DOM
  • Функции-утилиты
  • Обработка событий
  • Ajax

При рассмотрении функциональности я буду приводить примеры из одной или нескольких следующих инфраструктур JavaScript: Prototype, jQuery, YUI, ExtJS и MooTools. Хотя реализация и синтаксис разных инфраструктур различны, основные концепции остаются одинаковыми. Каждая инфраструктура предоставляет подробный справочник по API, к которому можно обращаться, чтобы понять, как использовать данную функциональность в той или иной библиотеке.


Селекторы

В большинстве имеющихся инфраструктур JavaScript реализована какая-либо форма селекторов - методов для быстрого выбора элементов. Селекторы значительно ускоряют процесс получения ссылки на нужный HTML-элемент. Они позволяют искать элементы по ID, имени класса, типу элемента или с помощью последовательности псевдоселекторов.

Например, с помощью обычного JavaScript можно выбрать DOM-элемент по ID с помощью следующего кода:

var theElement = document.getElementById('the_element');

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

var theElement = $('the_element');

Показанная выше функция $ доступна в нескольких (но не всех) популярных инфраструктурах JavaScript. Библиотека Prototype, кроме этого, позволяет выбирать по ID несколько элементов, возвращая массив элементов. Как и в MooTools, возможности этих элементов расширяются рядом дополнительных функций Prototype. Для одновременного выбора нескольких элементов в Prototype используется следующий синтаксис:

var elementArray = $('element_one', 'element_two', 'element_three');

В разделе Служебные функции вы узнаете о ряде предоставляемых инфраструктурами JavaScript функций, облегчающих итеративный обход коллекций объектов.

В предыдущих примерах поиск осуществлялся по ID конкретного элемента. Что делать, если мы хотим найти несколько элементов, например, все картинки или все строки таблицы с определенным именем CSS-класса? MooTools (и некоторые другие библиотеки) предоставляет для этого очень простой метод - функцию $$. Она работает по аналогии с функцией $, за исключением того, что вместо ID элемента она может принимать в качестве аргумента имя CSS-элемента, имя класса или псевдоселектор. Например, чтобы выбрать все изображения с Web-страницы с помощью MooTools, следует использовать следующий код:

var allImages = $$('img');

Этот код возвращает массив элементов, представляющих все имеющиеся в документе изображения, для каждого из которых доступны служебные функции MooTools.

Выбор элементов по имени тега - это полезная функциональность, но что если мы хотим выбрать некое подмножество элементов по имени CSS-класса? Это тоже очень просто. В следующем примере MooTools выберет все строки таблицы с CSS-классом "odd". Это может быть полезно для реализации чередования цвета фона в строках таблицы:

var allOddRows = $$('tr.odd');

На самом деле MooTools предлагает еще лучший способ реализации чередования фона строк. В предыдущем примере предполагалось, что каждая нечетная строка таблицы принадлежит к CSS классу с именем "odd". Следующий код не требует определения какого-либо CSS-класса для строк таблицы:

var allOddRows = $$('tbody:odd');

Здесь представлен пример псевдоселектора, который возвращает все объекты, удовлетворяющие спецификации, - в данном случае каждый нечетный элемент, являющийся потомком элемента tbody (тело таблицы). Вот еще несколько примеров псевдоселекторов MooTools:

  • checked— выбирает все помеченные элементы (например, все помеченные флажки)
  • enabled— выбирает все активные элементы
  • contains— выбирает все элементы, содержащие текст, переданный в селектор в качестве аргумента (например, contains('this text'))

Как упоминалось ранее, не все инфраструктуры JavaScript используют функцию $ для выбора элементов модели DOM. В библиотеке YUI (Yahoo! User Interface) версии 3 для выбора элемента по ID используется следующий код (обратите внимание, что в YUI 3 перед ID элемента необходимо указывать символ #):

var theElement = Y.one('#the_element');

Аналогичным образом вместо использования функции $$ для извлечения элементов по имени тега или класса в YUI применяется функция Y.all:

var allOddRows = Y.all('tr.odd');

ExtJS работает схожим образом. Для выбора элемента по ID в нем используется следующий синтаксис:

var theElement = Ext.get('the_element');

А для выбора элементов по имени тега или класса используется следующий синтаксис:

var allOddRows = Ext.select('tr.odd');

В следующем разделе мы увидим, как инфраструктуры JavaScript позволяют осуществлять обход дерева DOM, или, другими словами, находить элементы, являющиеся родственными (например, родителем, потомком или братом) определенному элементу. Также мы узнаем, как инфраструктуры позволяют манипулировать моделью DOM, чтобы изменять ее элементы.


Обход DOM-дерева

Поиск элемента по ID, типу элемента или имени CSS-класса - это очень полезная функциональность, но что если мы хотим найти элемент на основе его позиции в дереве DOM-модели? Например, мы хотим, имея определенный элемент, найти его родительский элемент, один из его потомков или же предыдущий или следующий элемент-брат. Рассмотрим пример разметки HTML, показанной в листинге 1.

Листинг 1. HTML таблица
<table>
    <thead>
        <tr>
            <th>Name</th>
            <th>Email Address</th>
            <th>Actions</th>
        </tr>
    </thead>
    <tbody>
        <tr id="row-001">
            <td>Joe Lennon</td>
            <td>joe@joelennon.ie</td>
            <td><a href="#">Edit</a>&nbsp;
                <a href="#">Delete</a></td>
        </tr>
        <tr id="row-002">
            <td>Jill Mac Sweeney</td>
            <td>jill@example.com</td>
            <td><a href="#">Edit</a>&nbsp;
                <a href="#">Delete</a></td>
        </tr>
    </tbody>
</table>

В листинге 1 используются отступы для иллюстрации того, где в DOM-дереве находится каждый элемент. В этом примере элемент table является корневым элементом, у него имеется 2 потомка - элементы thead и tbody. Единственным потомком элемента thead является элемент tr, который в свою очередь имеет трех потомков - элементы th. Потомками элемента tbody являются два элемента tr, каждый из которых имеет в свою очередь трех потомков. Третий потомок в каждой из этих строк имеет еще двух потомков - теги a .

Как вы знаете, для простого выбора элемента по ID можно использовать функцию-селектор какой-либо инфраструктуры JavaScript. В данном примере у нас есть два элемента с атрибутами ID — это элементы tr (строки таблицы), ID которых равны row-001 и row-002 соответственно. Для выбора первого элемента tr с помощью Prototype можно было бы использовать следующий код:

var theRow = $('row-001');

В предыдущем разделе мы также узнали о том, что селекторы можно использовать для извлечения элементов на основе их типа или CSS-класса. В этом примере мы можем выбрать все элементы td, используя следующий синтаксис:

var allCells = $$('td');

Проблема этого кода в том, что он возвращает абсолютно все элементы td из модели DOM. Но что делать, если мы хотим получить только элементы td, находящиеся в строке с ID равным row-001? Именно здесь на сцене появляются функции обхода DOM-дерева. Сначала давайте с помощью Prototype выберем всех потомков элемента tr с ID равным row-001:

var firstRowCells = theRow.childElements();

Этот код возвращает массив потомков переменной theRow (в которую мы ранее поместили элемент с ID равным row-001).

Далее, предположим, мы хотим получить только первого потомка, т.е., в данном случае, элемент td с текстом "Joe Lennon". Для этого мы используем следующую инструкцию:

var firstRowFirstCell = theRow.down();

Не правда ли, просто? Данная инструкция эквивалентна следующему коду:

var firstRowFirstCell = theRow.childElements()[0];

и также может быть записана в виде:

var firstRowFirstCell = theRow.down(0);

В JavaScript индексы начинаются с нуля, поэтому предыдущая инструкция указывает JavaScript выбрать первого потомка. Чтобы выбрать второго потомка (ячейку с адресом электронной почты - joe@joelennon.ie) можно использовать следующий код:

var firstRowSecondCell = theRow.down(1);

Также при обходе DOM-дерева можно использовать функции для перемещения по элементам-братьям. В нашем случае вторая ячейка является следующим братом по отношению к первой ячейке, поэтому можно использовать следующую инструкцию:

var firstRowSecondCell = firstRowFirstCell.next();

Эта функция работает точно так же как функция down(), поэтому, чтобы выбрать третью ячейку, следует использовать следующий код:

var firstRowThirdCell = firstRowFirstCell.next(1);

Помимо использования индексов для нахождения определенных узлов, Prototype также позволяет использовать синтаксис CSS-селекторов. Используя разметку из листинга 1, давайте найдем вторую ссылку (ссылку "Delete") для строки, содержащей подробную информацию о Jill Mac Sweeney:

var secondRowSecondLink = $('row-002').down('a', 1);

В этом примере мы используем функцию $ для поиска элемента с ID равным row-002, и спускаемся вниз по дереву DOM до второго относительно нас элемента a.

Некоторые инфраструктуры также позволяют объединять функции обхода дерева в цепочки, т.е. соединять вместе несколько команд обхода. С помощью Prototype найти элемент из предыдущего примера можно и другим способом:

var secondRowSecondLink = $('row-002').down('a').next();

Рассмотрим следующий пример:

var domTraversal = $('row-001').down().up().next().previous();

Как можно видеть, цепочки позволяют соединять вместе несколько инструкций обхода DOM-дерева. В действительности приведенный выше код просто выбирает элемент tr с ID row-001, т.е. цепочка команд приводит нас обратно к тому элементу, с которого мы начинали!


Манипуляции с DOM-деревом

Ранее мы видели, как имеющиеся в инфраструктурах Javascript селекторы и функции обхода DOM-дерева облегчают выбор нужных элементов. Однако для того, чтобы изменять внешний вид или содержимое какого-либо элемента Web-страницы, нам нужно уметь манипулировать моделью DOM. Это может быть весьма непросто при использовании исключительно JavaScript, но, к счастью, большинство инфраструктур JavaScript предлагают ряд полезных функций, облегчающих этот труд.

Допустим, у нас есть элемент div с id равным the-box:

<div id="the-box">Message goes here</div>

Поменять текст "Message goes here" с помощью jQuery можно следующим образом:

$('#the-box').html('This is the new message!');

На самом деле браузер сумеет понять код и в случае если внутри этой функции использовать разметку HTML. Например:

$('#the-box').html('This is the <strong>new</strong> message!');

В этом примере содержимое элемента div будет выглядеть в модели DOM следующим образом:

<div id="the-box">This is the <strong>new</strong> message!</div>

Конечно, иногда бывает необходимо использовать специальные символы, такие как знаки «больше» или «меньше». В таких случаях вместо указания специальных символов HTML, можно использовать имеющуюся в jQuery функцию text:

$('#the-box').text('300 > 200');

В результате обновленный div-элемент будет выглядеть так:

<div id="the-box">300 > 200</div>

В предыдущих примерах мы заменяли существующее содержимое новым содержимым. Но что если мы хотим просто добавить что-то к существующему тексту? К счастью, в jQuery специально для этих целей предусмотрена функция append:

$('#the-box').append(', here goes message');

После этого вызова наш элемент div будет выглядеть так:

<div id="the-box">Message goes here, here goes message</div>

Можно добавлять содержимое не только в конец элемента, но и в его начало, перед существующими данными (функция prepend). Также jQuery предлагает функции для вставки содержимого за границы данного элемента, перед ним или после него. Кроме того, имеются функции для замены или очистки содержимого, удаления элементов из модели DOM, клонирования элементов и т.д.

Кроме функций для изменения модели DOM, в инфраструктурах JavaScript обычно имеется несколько функций для манипулирования стилями и CSS-классами элементов. Допустим, мы хотим подсвечивать строку таблицы при наведении на нее курсора мыши. Мы создаем специальный CSS-класс с именем hover и хотим динамически добавлять строке этот класс. В инфраструктуре YUI можно использовать следующий код для проверки того, имеет ли уже строка класс hover, удаляет его, если класс присутствует, и добавляет его, если класса нет:

if(row.hasClass('hover')) row.removeClass('hover'); else row.addClass('hover');

Функции для манипулирования CSS встроены в большинство инфраструктур JavaScript.


Служебные функции

Большинство инфраструктур JavaScript поставляются в комплекте с огромным количеством служебных функций, облегчающих разработку приложений на JavaScript. Служебных функций слишком много для того, чтобы рассказать обо всех них в данной статье, поэтому мы рассмотрим одну из наиболее примечательных функций, типичных для большинства инфраструктур.

Если вы работали в JavaScript с массивами, возможно, вам приходилось использовать циклы for для обхода массива и получения значений его элементов. Например, рассмотрим код, представленный в листинге 2:

Листинг 2. Традиционный метод обхода массива в JavaScript
var fruit = ['apple', 'banana', 'orange'];
for(var i = 0; i < fruit.length; i++) {
    alert(fruit[i]);
}

Код, приведенный в листинге 2, неплохой, но немного неуклюжий. В большинстве инфраструктур JavaScript имеется функция each, которая вызывает указанную функцию для каждого элемента массива. Например, используя MooTools, выполнить действие, указанное в листинге 2, можно следующим образом:

Листинг 3. Использование функции each в MooTools
['apple', 'banana', 'orange'].each(function(item) {
    alert(item);
});

Синтаксис работы с функцией each одинаков для Prototype и jQuery, но немного отличается в YUI и ExtJS. Однако при работе не с массивом, а со словарем или объектом в разных инфраструктурах используется различный синтаксис функции each. Например, в MooTools можно использовать следующий код:

Листинг 4. Использование функции each для обхода объекта с парами ключ-значение в MooTools
var hash = new Hash({name: "Joe Lennon", email: "joe@joelennon.ie"});
hash.each(function(value, key) {
    alert(key + ": " + value);
});

В Prototype это бы выглядело иначе:

Листинг 5. Использование функции each для обхода объекта с парами ключ-значение в Prototype
var hash = $H({name: "Joe Lennon", email: "joe@joelennon.ie"});
hash.each(function(pair) {
    alert(pair.key + ": " + pair.value);
});

В каждой инфраструктуре имеется множество служебных функций, которые обычно подразделяют на функции по работе со строками, числами, массивами, словарями, датами и т.д. За более подробной информацией обращайтесь к руководству по API интересующей вас инфраструктуры.


Обработка событий

Во всех инфраструктурах JavaScript реализована кросс-браузерная поддержка обработки событий, которая поощряет переход от старомодной inline-обработки событий к более простому методу. Рассмотрим в листинге 6 пример работы с jQuery, в котором мы подсвечиваем элемент div на основе события hover.

Листинг 6. Обрабатываем в jQuery событие hover
$('#the-box').hover(function() {
   $(this).addClass('highlight');
}, function() {
   $(this).removeClass('highlight');
});

hover - это особое событие, реализуемое в jQuery. Оно предоставляет две функции: первая вызывается при наступлении события onMouseOver, а вторая - при наступлении события onMouseOut. В модели DOM нет стандартного события hover (отражающего состояние, когда на объект наведена мышь), поэтому приходится определять две функции. Давайте рассмотрим более типичное событие, например click (см. листинг 7).

Листинг 7. Обрабатываем в jQuery событие click
$('#the-button').click(function() {
   alert('You pushed the button!');
});

Как видно, в этом примере событие принимает в виде аргумента только одну функцию-обработчик. Большинство событий JavaScript обрабатывается в jQuery именно таким образом. При использовании обработчиков jQuery контекстная переменная указывает на элемент, на котором произошло данное событие. Некоторые инфраструктуры работают иначе. Например, рассмотрим, как код, приведенный в листинге 7, будет выглядеть в Prototype.

Листинг 8. Обрабатываем в Prototype событие click
$('the-button').observe('click', function(e) {
    alert('You pushed the button!');
});

Во-первых, заметим, что здесь вместо функции click используется функция observe, которая принимает в качестве аргументов название события и ссылку на функцию. Также заметим, что функция принимает аргумент e. Это контекстная переменная, указывающая на элемент, на котором произошло данное событие. Чтобы увидеть ее в работе, давайте перепишем для Prototype код из листинга 6 (см. листинг 9).

Листинг 9. Обрабатываем в Prototype событие hover
$('the-box').observe('mouseover', function(e) {
    var el = Event.element(e);
    el.addClassName('highlight');
});
$('the-box').observe('mouseout', function(e) {
    var el = Event.element(e);
    el.removeClassName('highlight');
});

В отличие от jQuery, где для получения контекстной переменной просто используется функция $, в Prototype нужно использовать функцию Event.element(). Также для обработки событий mouseover и mouseout нам пришлось использовать отдельные функции.

Вы могли заметить, что во всех примерах этой статьи мы создаем неименованные inline-функции. Это означает, что их нельзя повторно использовать. Пример обработки события hover в Prototype предоставляет нам возможность показать, как можно использовать вместо них именованные функции.

Листинг 10. Улучшенный пример обработки события hover в Prototype
function toggleClass(e) {
    var el = Event.element(e);
    if(el.hasClassName('highlight')) 
        row.removeClassName('highlight');
    else 
        row.addClassName('highlight');
}

$('the-box').observe('mouseover', toggleClass);
$('the-box').observe('mouseout', toggleClass);

Обратите внимание, что в этот раз мы просто определяем отдельную функцию, которая вызывается и при событии mouseover, и при mouseout. Эта функция определяет, имеется ли у элемента имя класса highlight, и в зависимости от результата либо удаляет, либо добавляет его. Обратите внимание, что аргумент e передается неявно. Другими словами, мы не передаем явно событие в качестве аргумента при вызове функции observe.


Ajax

Одной из весомых причин использования инфраструктур JavaScript является стандартизованная кросс-браузерная обработка запросов Ajax. Запрос Ajax представляет собой асинхронный HTTP-запрос к сценарию на сервере, который возвращает ответ в таком формате, как XML, JSON, HTML или обычный текст. В большинстве инфраструктур JavaScript имеются объекты, представляющие запросы Ajax. Обычно у этих объектов есть метод для отправки запроса, принимающий ряд параметров. В число этих параметров, как правило, входит функция обратного вызова, которая вызывается при получении ответа от Web-сервера. Давайте посмотрим, как выглядят Ajax-запросы в ExtJS, MooTools и Prototype.

Давайте сначала взглянем на типичный Ajax-запрос в ExtJS (см. листинг 11).

Листинг 11. Ajax-запрос в ExtJS
Ext.Ajax.request({
    url: 'server_script.php',
    params: {
        name1: 'value1',
        name2: 'value2'
    },
    method: 'POST',
    success: function(transport) {
        alert(transport.responseText);
    }
});

Здесь метод request принимает единственный аргумент - объект с множеством полей, в числе которых url, params, method и success. Поле url содержит URL серверного сценария, который будет вызываться Ajax-запросом. Поле params само является объектом, состоящим из пар ключ/значение, которые будут переданы серверному сценарию в качестве параметров. Поле method может принимать одно из двух значений: GET или POST. По умолчанию его значение не определено, но оно будет считаться POST, если в запросе задано поле params. В последнем поле, success, задается функция, которая будет вызвана, когда Web-сервер вернет успешный результат. В данном примере предполагается, что серверный сценарий возвращает обычный текст и данная функция отображает этот текст в окне предупреждения.

Теперь давайте посмотрим, как тот же самый запрос выглядит в MooTools (см. листинг 12).

Листинг 12. Ajax-запрос в MooTools
new Request({
    url: 'server-script.php',
    data: {
        name1: 'value1',
        name2: 'value2'
    },
    method: 'post',
    onComplete: function(response) {
        alert(response);
    }
}).send();

Как видно, в данном случае код MooTools очень похож на код ExtJS. Здесь вместо поля params параметры запроса передаются в поле data, а тип метода необходимо указывать в нижнем регистре. Также в MooTools поле, где указывается функция обратного вызова, называется onComplete, а не callback. Наконец, в MooTools, в отличие от ExtJS, необходимо посылать запрос с помощью функции send() объекта Request.

А сейчас давайте посмотрим, есть ли радикальные различия в работе с Ajax с помощью Prototype (см. листинг 13).

Листинг 13. Ajax-запрос в Prototype
new Ajax.Request('server-script.php', {
    params: {
        name1: 'value1',
        name2: 'value2'
    },
    method: 'post',
    onSuccess: function(transport) {
        alert(transport.responseText);
    }
});

Как видно, Prototype работает аналогичным образом, лишь с небольшими синтаксическими отличиями. Для начинающих поясним, что объект Request в Prototype принимает в своем конструкторе два параметра. Первым параметром является URL-адрес, по которому следует послать Ajax-запрос, а второй параметр - это объект с атрибутами запроса, похожий на объекты, которые мы видели в предыдущих примерах. Конечно же, поскольку здесь URL передается отдельным параметром, его нет среди атрибутов данного объекта. Также стоит заметить, что в отличие от MooTools в Prototype не нужно вызывать какой-либо метод, чтобы послать запрос, это делается неявно конструктором объекта Request.

Поддержка Ajax в большинстве инфраструктур JavaScript не ограничивается тем, что мы здесь рассмотрели. Среди прочих возможностей стоит отметить автоматическое обновление элемента при получении ответа, без необходимости определения специальных функций обратного вызова, таких как onSuccess. В некоторые библиотеки даже встроена функция автоматического дополнения, наподобие того, что можно наблюдать на странице поиска Google, когда при вводе текста предлагаются варианты типичных поисковых запросов.

В следующем разделе мы узнаем о пользовательских расширениях, предлагаемых Web-разработчикам инфраструктурами JavaScript.


Пользовательские расширения

До этого момента мы в данной статье рассматривали преимущества использования инфраструктур JavaScript с точки зрения разработки и того, как они облегчают кодирование интерактивных приложений. Однако большинство инфраструктур предлагают еще один привлекательный аспект: компоненты пользовательского интерфейса (UI) и легко подключаемые пользовательские расширения, самостоятельная разработка которых потребовала бы значительных усилий.

В этом разделе мы по отдельности изучим пользовательские расширения, предлагаемые следующими инфраструктурами: Prototype, jQuery, YUI, ExtJS и MooTools.

Prototype

Prototype - это одна из немногих инфраструктур JavaScript, в составе которых по умолчанию отсутствуют UI-компоненты или пользовательские расширения. Все они находятся в родственной библиотеке - script.aculo.us (ее последняя версия известна под именем Scripty2). Script.aculo.us добавляет в Prototype поддержку множества эффектов и разнообразного поведения. Среди этих эффектов можно отметить подсветку, изменения формы, складывание, покачивание, скольжение, вздутие и т.д.. Script.aculo.us также известна поддержкой функциональности drag-and-drop, а также слайдеров, редактирования "на месте" и автодополнения. В отличие от некоторых других инфраструктур Script.aculo.us не предоставляет стандартных тем, оставляя разработчикам все заботы по разработке дизайна всех элементов управления.

jQuery

В отличие от Prototype, в jQuery некоторые базовые пользовательские расширения включены в ядро библиотеки. Эти расширения похожи на некоторые из эффектов, имеющихся в script.aculo.us, например скольжение и затухание. Однако более сложные эффекты содержатся в отдельной библиотеке jQuery UI. Эта библиотека также поддерживает интерактивные возможности, такие как drag and drop, изменение размера элементов и сортировку. В отличие от script.aculo.us, библиотека jQuery UI также включает в себя набор виджетов и компонентов, существенно облегчающих разработку привлекательных пользовательских интерфейсов. На данный момент в ней имеются такие компоненты, как Accordion, Datepicker, Dialog, Progressbar, Slider и Tabs. Также jQuery UI предлагает большое количество готовых тем, в которые можно интегрировать виджеты и компоненты при разработке сайта или Web-приложения. На рисунке 1 показан пример Datepicker в теме Cupertino.

Рисунок 1. Виджет Datepicker библиотеки jQuery UI
A screen showing the datepicker demo as well as a calendar beneath the title Datepicker.

YUI

В отличие от Prototype и jQuery, где нет доступных "из коробки" графических виджетов, в библиотеке Yahoo! User Interface library (YUI) их имеется множество. Помимо поддержки drag-and-drop и изменения размера элементов, 2-я версия YUI включает в себя элементы для управления автодополнением и календарем, вращающиеся по карусели компоненты, таблицы, диалоги, индикаторы прогресса, текстовые редакторы (или текстовые поля WYSIWYG), слайдеры, вкладки, деревья и многое другое. На момент написания этой статьи ни один из вышеупомянутых виджетов не был включен в 3-ю версию YUI. На рисунке 2 показан пример графического интерфейса, созданного с помощью данных компонентов.

Рисунок 2. Пример сложного приложения на основе YUI
Screen showing an e-mail program with a window open to enter image options such as image url and size.

ExtJS

Как и в YUI, в библиотеке ExtJS доступно "из коробки" множество компонентов, среди которых стоит особо отметить очень мощные средства для создания сеток элементов, поддерживающие редактирование "на месте", постраничный просмотр, фильтры, группировки, обобщенные представления, буферизацию и связывание с данными. Компоненты ExtJS выглядят очень профессионально и настраиваются посредством тем. Также в ExtJS имеются такие виджеты, как вкладки, таблицы, окна (диалоги), деревья, менеджеры разметки, дополнительные элементы управления на формах, панели инструментов и меню, drag-and-drop и direct remoting. Это лишь малая часть того, что может предложить ExtJS, поэтому если вы ищете обширный набор компонентов для разработки приложений с насыщенным пользовательским интерфейсом, обязательно посетите web-сайт ExtJS. На рисунке 3 показан пример разработанного с помощью ExtJS рабочего стола, иллюстрирующий, насколько богатая функциональность доступна в этой библиотеке.

Рисунок 3. Приложение "Рабочий стол", разработанное с помощью ExtJS
Screen showing an example of a grid window, an application window, and a tab window.

MooTools

Так же как Prototype и jQuery, MooTools не предоставляет "из коробки" виджеты и элементы управления. Как и в jQuery, в ядро библиотеки включен лишь ограниченный набор графических эффектов. Более сложные пользовательские расширения доступны в дополнительной библиотеке MooTools.More.js. В ней помимо графических расширений имеется ряд интересных надстроек над классами Array, Date, Hash и String, а также расширения класса Element. Говоря о графических расширениях MooTools.More.js, следует упомянуть поддержку drag-and-drop и некоторых других эффектов. Также в этом расширении имеются такие графические элементы управления, как accordion, сортируемые HTML-таблицы, элементы прокрутки, контекстные подсказки и spinner-ы, работающие с Ajax. Однако, как и в случае с script.aculo.us, разрабатывать их дизайн вам придется самостоятельно.


Сравнение инфраструктур

В таблице 1 представлено детальное сравнение функциональности пяти инфраструктур, которые мы обсуждали в данной статье.

Таблица 1. Сравнение функциональности инфраструктур
PrototypejQueryYUIExtJSMooTools
Последняя версия1.6.11.4.13.003.11.2.4
ЛицензияMITMIT & GPLBSDКоммерческая & GPL v3MIT
Поддержка браузеров
Поддержка IE6.0+6.0+6.0+6.0+6.0+
Поддержка Firefox1.5+2.0+3.0+1.5+2.0+
Поддержка Safari2.0.4+3.0+4.0+3.0+2.0+
Поддержка Opera9.25+9.0+10.0+9.0+9.0+
Поддержка Chrome1.0+1.0+НеизвестноНеизвестноНеизвестно
Главная функциональность
Поддержка AjaxЕстьЕстьЕстьЕстьЕсть
Манипуляция DOM-деревомЕстьЕстьЕстьЕстьЕсть
Обход DOM-дереваЕстьЕстьЕстьЕстьЕсть
Обработка событийЕстьЕстьЕстьЕстьЕсть
JSONЕстьЕстьЕстьЕстьЕсть
СелекторыЕстьЕстьЕстьЕстьЕсть
Графические пользовательские расширения
AccordionНетjQuery UIНетЕстьMooTools More
АнимацияscriptaculousЕстьЕстьЕстьЕсть
АвтодополнениеscriptaculousНетЕстьЕстьНет
История браузераscriptaculousНетЕстьЕстьНет
КалендарьНетjQuery UIЕстьЕстьНет
ТаблицыНетНетЕстьЕстьНет
Drag and DropscriptaculousjQuery UIЕстьЕстьMooTools More
СеткиНетНетЕстьЕстьMooTools More
Индикатор прогрессаНетjQuery UIЕстьЕстьНет
Изменение размера элементовНетjQuery UIЕстьЕстьНет
Сложный текстовый редакторНетНетЕстьЕстьНет
СлайдерыscriptaculousjQuery UIЕстьЕстьMooTools More
ВкладкиНетjQuery UIЕстьЕстьНет
ТемыНетjQuery UIЕстьЕстьMooTools More
Древовидные структурыНетНетЕстьЕстьНет

Другие инфраструктуры

В целях краткости в данной статье мы рассмотрели только пять популярных инфраструктур разработки JavaScript. Это не обязательно означает, что эти инфраструктуры самые популярные, самые лучшие и предлагают наиболее богатую функциональность.

В числе других заслуживающих внимания инфраструктур JavaScript можно указать:

  • Cappuccino
  • Dojo
  • Glow
  • GWT
  • MochiKit
  • Qooxdoo
  • Rialto
  • Rico
  • SproutCore
  • Spry
  • UIZE

Заключение

В этой статье мы познакомились с концепцией инфраструктур JavaScript и узнали о преимуществах, которые инфраструктуры предоставляют при разработке Web-сайтов и Web-приложений. Мы рассмотрели некоторые типичные возможности, предоставляемые инфраструктурами, а также несколько примеров того, как эта функциональность реализуется в наиболее популярных библиотеках. Далее мы узнали о пользовательских расширениях, поставляемых либо в комплекте с инфраструктурой, либо в виде дополнительной библиотеки. В заключение мы подытожили сведения об этих инфраструктурах в таблице, чтобы можно было более наглядно сравнить их возможности. Вооружившись данной информацией, вы должны быть готовы к дальнейшему изучению этих инфраструктур и последующему принятию обоснованного решения о том, какая из них лучше подходит вам и вашей команде разработчиков.

Ресурсы

Научиться

  • Ознакомьтесь с оригиналом статьи: "Compare JavaScript frameworks".(EN)
  • В статье "Build apps using Asynchronous JavaScript with XML (AJAX)" (developerWorks, ноябрь 2005 г.) рассказывается, как создавать основанные на Ajax Web-приложения.(EN)
  • Познакомьтесь с инфраструктурой Dojo.
  • Прочитайте статью "Dojo concepts for Java developers" (developerWorks, октябрь 2008 г.), чтобы узнать, как сократить разрыв между кодом на Java и Dojo и быстро научиться использовать этот набор инструментов для разработки приложений.(EN)
  • Прочтите статью "Call SOAP Web services with Ajax, Part 1: Build the Web services client" (developerWorks, октябрь 2005г.), чтобы узнать, как с помощью Ajax создать основанный на Web-браузере клиент SOAP Web-сервисов.(EN)
  • В статье "Overcome security threats for Ajax applications" (developerWorks, июнь 2007 г.) автор обсуждает угрозы безопасности, связанные с технологией Ajax и делится практическими рекомендациями, позволяющими их избегать.(EN)
  • В статье "Mastering Ajax, Part 1: Introduction to Ajax" (developerWorks, декабрь 2005 г.) рассказывается о том, как с помощью технологий HTML, JavaScript, DHTML и DOM сделать Web-разработку чрезвычайно эффективной и простой.
  • В статье "Simplify Ajax development with jQuery" (developerWorks, апрель 2007 г.) авторы рассматривают философию инфраструктуры jQuery, рассказывают о ее возможностях и функциях и показывают несколько типичных примеров работы с Ajax.(EN)
  • В статье "Using Ajax with DB2" (developerWorks, август 2007г.) рассказывается о том, как технология Ajax применялась в приложении IBM Information on Demand 2006 Conference Personal Planner для работы с DB2®. (EN)
  • Слушайте интересные интервью и дискуссии разработчиков ПО в разделе подкастов developerWorks. (EN)
  • Следите за новостями в разделе технических мероприятий и web-трансляций developerWorks. (EN)

Получить продукты и технологии

  • Загрузите набор инструментов Dojo toolkit.(EN)
  • Загрузите инфраструктуру Prototype. (EN)
  • Загрузите jQuery.(EN)
  • Библиотека jQuery User Interface предоставляет построенный на основе Javascript уровень абстракции для низкоуровневых взаимодействий и анимации, сложных эффектов и высокоуровневых виджетов, поддерживающих темы.(EN)
  • Загрузите script.aculo.us.(EN)
  • Загрузите MooTools. (EN)
  • Загрузите и познакомьтесь с предоставляемой Yahoo! библиотекой YUI Library.(EN)
  • Загрузите ExtJS. (EN)
  • Разработайте свой следующий проект с помощью пробного ПО от IBM, которое можно загрузить непосредственно с сайта developerWorks или заказать на DVD.(EN)
  • Загрузите пробные версии продуктов IBM, чтобы получить практический опыт работы с инструментами разработки приложений и ПО промежуточного уровня от DB2, Lotus®, Rational®, Tivoli® и WebSphere®.(EN)

Комментарии

developerWorks: Войти

Обязательные поля отмечены звездочкой (*).


Нужен IBM ID?
Забыли Ваш IBM ID?


Забыли Ваш пароль?
Изменить пароль

Нажимая Отправить, Вы принимаете Условия использования developerWorks.

 


Профиль создается, когда вы в первый раз заходите в developerWorks. Выберите данные в своем профиле (имя, страна/регион, компания) которые будут общедоступными и будут отображаться, когда вы публикуете какую-либо информацию. Вы можете изменить данные вашего ИБМ аккаунта в любое время.

Вся введенная информация защищена.

Выберите имя, которое будет отображаться на экране



При первом входе в developerWorks для Вас будет создан профиль и Вам нужно будет выбрать Отображаемое имя. Оно будет выводиться рядом с контентом, опубликованным Вами в developerWorks.

Отображаемое имя должно иметь длину от 3 символов до 31 символа. Ваше Имя в системе должно быть уникальным. В качестве имени по соображениям приватности нельзя использовать контактный e-mail.

Обязательные поля отмечены звездочкой (*).

(Отображаемое имя должно иметь длину от 3 символов до 31 символа.)

Нажимая Отправить, Вы принимаете Условия использования developerWorks.

 


Вся введенная информация защищена.


static.content.url=http://www.ibm.com/developerworks/js/artrating/
SITE_ID=40
Zone=Web-архитектура, Технология Java
ArticleID=599323
ArticleTitle=Сравниваем инфраструктуры для разработки на JavaScript
publish-date=12082010