jQuery — волшебный фреймворк
материал посвящен обзору возможностей jQuery-библиотеки и JavaScript-фрейморвка
jQuery — это популярный сегодня JavaScript-фреймворк, основной функцией которого является обеспечение взаимодействия между HTML и JavaScript на странице. Был создан Джоном Ресигом и впервые опубликован на конференции BarCamp в 2006 году. jQuery обладает следующими возможностями:
- переход по дереву DOM, включая поддержку XPath как плагина;
- события;
- визуальные эффекты;
- AJAX-дополнения;
- JavaScript-плагины.
Основным конкурентом jQuery является другой JavaScript-фреймворк под названием Prototype. Он упрощает работу с Ajax и иными функциями и доступен в виде отдельной библиотеки, однако обычно используется разработчиками вместе с script.aculo.us, Rico и Ruby on Rails. В Prototype присутствуют различные способы упрощения разработки JavaScript-приложений — начиная сокращенным вызовом некоторых функций и заканчивая сложными методами обращения к XMLHttpRequest. До недавнего времени у библиотеки Prototype было еще одно серьезное преимущество перед jQuery — поддержка объектно ориентированного программирования. Для создания нового класса в Prototype используется метод Class.create, которому присваивается прототип prototype (извиняюсь за тавтологию), который и выступает в качестве основы для каждого экземпляра класса. Классы могут быть расширены с помощью Object.extend.
Сама библиотека jQuery включается в веб-страницу как один внешний JavaScript-файл. Инициализация происходит следующим образом:
<head>
<script type="text/javascript" src="путь к jquery.js"></script>
</head>
Вызов методов jQuery может осуществляться двумя способами:
- Через функции $, являющиеся методами объекта jQuery. Их можно объединять в цепочку, так как каждая из них возвращает этот объект.
- Через функции $., не связанные с объектом jQuery.
Типичным примером манипуляции несколькими узлами DOM одновременно может являться вызов функции $ со строкой селектора CSS, что возвращает объект jQuery, содержащий некоторое количество элементов страницы. Эти элементы после обрабатываются методами jQuery. Например:
$("div.test").add("p.quote").addClass("blue").slideDown("slow");
Это найдет все элементы div с классом test и все элементы p с классом quote, а затем добавит им всем класс blue и визуально плавно опустит вниз.
Методы, которые начинаются с $., удобно применять для обработки глобальных объектов, например, следующий код добавит на страницу 234:
$.each([1,2,3], function() {
document.write(this + 1);
});
Использование $.ajax и соответствующей функции позволит использовать методы Ajax.
Как уже упоминалось, еще недавно jQuery заметно уступал подобным ему решениям типа Prototype по причине отсутствия грамотного ООП-подхода. Однако в конце марта Джон Ресиг, автор библиотеки jQuery, дополнил ее classy query. Как ни странно, сам создатель пока не советует использовать подобный подход, аргументируя это недостаточной проработанностью class query. Но в любом случае с точки зрения синтаксиса языка код на jQuery теперь будет выглядит вполне (фанатам Rails и Django ниже лучше не смотреть, дабы сохранить психическое равновесие на остаток дня) читабельно, например, так:
<script src="jquery.js"></script>
<script src="classy.js"></script>
<script>
jQuery.Events.addEventListener(document, "ready", function(){
jQuery.querySelectorAll("div").forEach(function(elem){
jQuery.DOM.append(elem, " <b>More...</b>"); });
jQuery.querySelectorAll("div b").forEach(function(elem){
jQuery.Events.addEventListener("click", function(elem, event){
var next = jQuery.Traversal.nextSibling(elem);
var animation = jQuery.Effects.buildAnimation( next, {height: "toggle"});
amimation.start();
});
});
});
</script>
Для работы с jQuery программисту или дизайнеру понадобятся знания не только JavaScript, но и CSS. Не думаю, что это кому-то может показаться странным: CSS нынче распространен очень широко, а селектор jQuery отталкивается именно от принципов CSS. Например:
- $("#header") — получение элемента с id="header";
- $("h3") — получить все элементы h3;
- $("div#content .photo") — получить все элементы с классом photo, которые находятся в элементе div с id="content";
- $("ul li") — получить все элементы li из списка ul;
- $("ul li:first") — получить только первый элемент li из списка ul.
Расширения — плагины и библиотеки jQuery — написаны в основном обычными разработчиками. В качестве более функциональных наработок со своим интерфейсом создается jQuery UI как аналог упомянутым Prototype и Scriptaculous, куда будут входить перетаскиваемые и сортируемые элементы и виджеты интерфейса — аккордеон, табы, слайдеры и многое другое. В конце статьи будет приведен список полезных плагинов для jQuery, заслуживающих пристального внимания.
Примером работы jQuery может являться следующее. Допустим, нам необходимо сделать массовое удаление чего угодно из списка, для чего генерируется огромный список checkbox, а для того, чтобы их массово выделить, можно создать глобальный checkbox:
<input type="checkbox" name="group[{$item.id}]" class="group_checkbox"
onchange="$('.group_checkbox').attr('checked',this.checked);">
Достаточно часто у разработчика или администратора ресурса встает вопрос оповещения пользователей о добавлении какого-то сервиса, ошибке или любой другой информации. Для этого можно использовать три CSS-класса, которые при этом будут «прятаться» по прошествии какого-то установленного времени. Для этого используется конструкция, запускающаяся после создания DOM-дерева, а не всего документа, которая выглядит так:
$(document).ready(function() { setTimeout(function() {$('.error').fadeOut('slow');}, 20000);});
Как и с любым другим языком программирования, чем больше разработчик разбирается в происходящем, тем более качественный код он способен производить. Это касается и jQuery, несмотря на то что большая часть руководств написана либо для людей, только начинающих изучение CSS и JavaScript, либо для дизайнеров и верстальщиков. Однако jQuery также может быть крайне полезна и опытным разработчикам, и вот почему.
Важным моментом в написании хорошего JavaScript-кода, который будет пригоден для дальнейшего использования, является тщательное управление пространством имен. В JavaScript оно единое и глобальное (объект window), и многие программисты, а также библиотеки засоряют его почем зря. Разумные же разработчики, в свою очередь, сводят к минимуму свое вторжение в это пространство, используя такие методы, как модульная модель.
jQuery вводит только один объект в глобальное пространство имен — это объект jQuery. Все остальное — это или свойство библиотеки, или метод объекта. Некоторые библиотеки напрямую расширяют встроенные в JS классы String и Array, что может быть небезопасно. String.prototype и Array.prototype являются самостоятельными глобальными пространствами имен, добавление каких-либо свойств в них может ввести опасность коллизий, связанных с использованием одних и тех же переменных. В jQuery имеются некоторые функции, расширяющие возможности JavaScript, но каждая из них является доступной как свойство объекта jQuery: .each; .extend; .grep; .map; .merge; .trim. Они по определению не могут конфликтовать с каким-либо другим кодом.
$, по сути, является сокращением для jQuery. Ввод этого символа производится достаточно мягко: если вам вдруг потребуется ваша прежняя функция $ (если есть, к примеру, часть кода на Prototype), вы можете просто вызвать jQuery.noConflict(), для того чтобы вернуть свою старую функцию $. Ну а если требуется ограничить использование функции $ для jQuery, не забивая себе голову переживаниями о возможных коллизиях при другом использовании функции $, документация jQuery предлагает следующее решение:
(function($) {
// Внутри этого блока $ относится к jQuery
// Изящно, правда?
})(jQuery);
Повсеместное использование $ в jQuery — это очень гибкое решение, которое по достоинству оценивают все разработчики, имеющие дело с этим фреймворком.
Каждый оператор jQuery начинается с выбора одного или нескольких узлов DOM. Синтаксис селекторов jQuery является гибридом спецификаций
- jQuery('div.panel') — все элементы div с class="panel";
- jQuery('p#intro') — элемент p с id="intro";
- jQuery('div#content a:visible') — все видимые ссылки внутри элемента div с id="content";
- jQuery('input[@name=email]') — все элементы input (поля ввода) с name="email";
- jQuery('table.orders tr:odd') — все четные строки в таблице с class="orders";
- jQuery('a[@href^="http://"]') — все внешние ссылки (те, которые начинаются с http://);
- jQuery('p[a]') — все элементы p, в которых есть хотя бы одна ссылка.
Наибольший интерес из всего этого представляют :visible и :odd, которые являются специфичными только для jQuery. Язык селекторов весьма богат и похож на регулярные выражения, так что время, потраченное на его изучение, вернется сторицей.
Некоторые разработчики считают, и вполне обоснованно, что лучшие веб-приложения — это те, которые могут полноценно функционировать при отключенных скриптах. Конечно же, лучшим решением для достижения такой цели является ненавязчивый JavaScript, когда события назначаются элементам только после того, как вся HTML-страница у пользователя загрузится полностью. И jQuery замечательно поддерживает этот подход. Парадигма селекторов для выбора узла является основополагающей как для jQuery, так и для ненавязчивого программирования в целом. jQuery обеспечивает решение проблемы window.onload, основанное на исследованиях Дена Эдвардса по работе события DOM loaded в различных браузерах. Вы можете выставить функцию-обработчик тогда, когда DOM будет к ней готов:
jQuery(document).ready(function() {
alert("DOM готов!");
});
И даже больше, вы можете сократить эту запись, назначив вашу функцию напрямую jQuery:
jQuery(function() {
alert("DOM готов!");
});
Нельзя обойти стороной и модный Ajax. У jQuery, по мнению некоторых, лучший API для работы с Ajax среди больших библиотек. Наиболее простая форма Ajax-вызова выглядит так:
jQuery("div#intro").load("/some/fragment.html");
Это выполнит GET-запрос к /some/fragment.html и вставит в div#intro HTML-код, который получит.
Но как поведет себя фреймворк, если потребуется что-то более сложное, скажем, индикатор Ajax-загрузки? jQuery предоставляет набор собственных событий: ajaxStart, ajaxCompete, ajaxError и других для использования. Присутствует и более продвинутый API низкого уровня для сложных Ajax-взаимодействий:
jQuery.get("/some/script.php", {"name": "Simon"}, function(data) {
alert("Сервер ответил: " + data);
}); // GET-запрос к /some/script.php?name=Simon
jQuery.post("/some/script.php", {"name": "Simon"}, function(data) {
alert("Сервер ответил: " + data);
}); // POST-запрос к /some/script.php
jQuery.getJSON("/some.json", function(json) {
alert("JSON выдал: " + json.foo + " " + json.bar);
}); // Возвращает и преобразует ответ от /some.json как JSON
jQuery.getScript("/script.js"); // GET-запрос к /script.js и eval()
В качестве заключения сказано немало фактов для составления своего, надеюсь положительного, мнения о jQuery. Она не является очередной библиотекой, а скорее исключительной. В ней заложена масса интересных идей, которые смогут удивить даже опытных JavaScript-программистов и научить их чему-то новому.
Как и было обещано — далеко не полный список интересных плагинов и расширений для jQuery.
Изображения
ThickBox — галерея, аналог lightbox.
FancyBox — еще одна галерея.
Galleria — галерея.
Multimedia portfolio — горизонтальный слайдер с видео, картинками и звуком.
imgAreaSelect — выделение области для вырезания.
Анимированный блок изображений, подходит при портфолио и панорамах.
Lightbox с более плавной анимацией, чем в Рrototype.
Таблицы
Flexigrid — табличные данные.
InGrid — Ajax-таблица, но не на JSON, а на открытом HTML.
Формы
DamnSmallRTE — маленький WYSIWYG.
NiceForms — обрамляет элементы input элементами div с закругленными углами, стилизует radio и checkbox.
FaceBook like — автоподсказки.
JQuery select — конвертирует все элементы select в ul, которые можно более гибко стилизовать.
MaskedInput — маска заполнения input-форм.
Закачка файлов с созданием элементов iframe.
Манипуляция checkbox и radio с превращением в iРhone-стиль.
jGrow — размер textarea в зависимости от размера текста.
jWYSIWYG — простейший редактор.
ajaxForm — формы для использования пересылки через Ajax.
DatePicker — показывает и генерирует календарик под указанными полями.
Layout
RoundedCorners — закругленные углы при помощи генерации элемента canvas.
CodaSlider — слайды в дополнение к вкладкам (tabs).