webew
Войти » Регистрация
 
JavaScript :: Библиотеки

jQuery для JavaScript

20 марта 2008, 12:35
Когда jQuery, библиотека JavaScript, увидела свет в январе 2006, все подумали: «очередная красивая игрушка». Выбор CSS-селекторов в качестве базиса было, конечно, изящной идеей, но использование цепочек преобразований выглядело немного замысловато, и сама библиотека, по-видимому, не покрывала всех возможных случаев. jQuery расценивали тогда только как временное и проходящее решение.

Только несколько месяцев спустя стало понятно, что jQuery является просто произведением инженерного искусства. Она умело покрывает достаточно широкий диапазон повседневных функций и предоставляет при этом удобный API для расширений, с помощью которых можно добавить любую другую функциональность. Абстрактность в ней заложена на уровне ядра — речь идет о выборе элементов объектной модели документов (DOM) — и она извлекает из него максимум пользы. И что важнее всего, использование этой библиотеки подразумевает следование хорошему стилю в программировании и хорошо сочетается с другими частями JavaScript-кода.

Большинство современных обзоров jQuery делают упор на дизайнеров и неопытных разработчиков. Я попытаюсь объяснить, почему она также нужна и опытным программистам.

Пространство имен (namespacing)
Ключевым моментом в создании хорошего JavaScript-кода для дальнейшего использования является тщательное управление пространством имен. В JavaScript существует единое глобальное пространство имен (объект window), и многие программисты (и даже некоторые библиотеки) засоряют его безо всякой надобности. Глобальные переменные — зло! Более благоразумные разработчики сводят к минимуму свое вторжение в это пространство, используя некоторые методы, например, модульную модель.
jQuery вводит единственный объект в глобальное пространство имен — функцию/объект jQuery. Все остальное — это либо непосредственное свойство jQuery, либо метод объекта, возвращаемого вызовом функции jQuery.

Что можно сказать об улучшениях языка? Большинство библиотек предоставляют некоторое подобие функций отображения, фильтрации и обрезания, которые, к несчастью, отсутствуют в тех движках JavaScript, которые включены в большинство браузеров. Некоторые библиотеки напрямую расширяют встроенные в JavaScript классы String и Array, но также не до конца безопасно. String.prototype и Array.prototype являются самостоятельными глобальными пространствами имен, и добавление в них каких-либо свойств влечет опасность коллизий, связанных с использованием одних и тех же имен переменных в разных контекстах.

В jQuery имеется некоторое количество функций, расширяющих возможность JavaScript, но каждая из них является доступной только как свойство объекта jQuery: jQuery.each, jQuery.extend, jQuery.grep, jQuery.map, jQuery.merge и jQuery.trim. Они по определению не будут конфликтовать с каким-либо другим кодом.

Печально известная функция $
На самом деле jQuery вводит не один символ в глобальное пространство имен, есть еще и $: он используется как сокращение для jQuery. Это производится достаточно мягко: если вам снова требуется ваша прежняя функция $ (например, если у вас есть часть кода, основанная на Prototype), вы можете вызвать jQuery.noConflict(), чтобы вернуть свою старую функцию $.
Если вам требуется ограничить использование функции $ для jQuery не опасаясь коллизий при каком-либо другом использовании глобальной функции $, документация по jQuery предлагает следующий способ:

(function($) {
   // Внутри этого блока $ относится к jQuery
   // Изящно, правда?
})(jQuery);


Повсеместное использование $ в jQuery не более, чем хитроумный трюк. Но если рассматривать его только в контексте jQuery, то такое решение выглядит очень гибким.

Выбираем элементы
Каждый jQuery-оператор начинается с выбора одного или нескольких узлов DOM. Синтаксис селекторов jQuery (внутренний язык этой библиотеки) является интересным гибридом спецификаций CSS 1, 2, немного CSS 3, немного XPath и еще малость других расширений. Не будем углубляться в детали, просто приведем несколько полезных примеров:
jQuery('div.panel')
Все div с class="panel"
jQuery('p#intro')
Параграф с id="intro"
jQuery('div#content a:visible')
Все видимые ссылки внутри div с id="content"
jQuery('input[@name=email]')
Все поля ввода с name="email"
jQuery('table.orders tr:odd')
Все четные строки в таблице с class="orders"
jQuery('a[@href^="http://"]')
Все внешние ссылки (те, которые начинаются с http://)
jQuery('p[a]')
Все параграфы, в которых есть хотя бы одна ссылка

Наибольший интерес из вышеописанного представляют :visible и :odd, которые являются специфичными только для jQuery. Стоит также отметить, что выбор атрибутов использует знак @, что более соответствует XPath нежели CSS 2.

Язык селекторов весьма богат и очень похож на регулярные выражения, так что время, потраченное на его изучение, окупится сполна.

Чего-нибудь с ними делаем
Объект, который возвращают селекторы jQuery, является довольно интересным зверем. Он представляет собой набор DOM-элементов и ведет себя немного как массив: у него есть свойство length, к его элементам можно получить доступ по индексу и (что более важно) Firebug расценивает его именно как массив при отображении в своей консоли. Это не более, чем красивая иллюзия: набор элементов, на самом деле, — это объект jQuery, у которого есть большое число методов для выбора, изменения или расширения имеющегося набора.
В jQuery имеется три разных категории методов: первые манипулируют со всеми элементами, которые подходят по шаблону, вторые возвращают значение от первого найденного элемента, и третьи изменяют саму выборку.

Не будем перечислять все доступные методы (это можно посмотреть и на visualjquery.com), но приведем некоторые примеры. Если у вас есть Firebug, вы можете попробовать их самостоятельно: просто нужно воспользоваться закладкой «Вставить jQuery» (javascript:void(function(){var s=document.createElement('script');
s.src='http://code.jquery.com/jquery-1.1.2.js'; document.getElementsByTagName('head')[0].appendChild(s);}()))
для загрузки самой библиотеки для любой страницы, а затем вставить примеры кода в консоль Firebug (прим.: можно и без Firebug: достаточно загрузить jQuery с помощью указанной ссылки и вызвать приведенные примеры в адресной строке браузера, не забыв в начале javascript: и какой-либо alert в конце (чтобы на страницу не выводилось возвращаемое значение)).

jQuery('div#primary').width(300);
Выставляет ширину div id="primary" в 300 пикселей.
jQuery('p').css('line-height', '1.8em');
Выставляет высоту строки в 1.8em для всех параграфов.
jQuery('li:odd').css({color: 'white', backgroundColor: 'black'});
Применяет 2 CSS-правила для каждого пункта списка; заметьте, что функция css() может принимать объект таблицы стилей вместо двух строк.
jQuery('a[@href^="http://"]').addClass('external').attr('target', '_blank');
Добавляет класс "external" для всех внешних ссылок (тех, что начинаются с http://), затем добавляет target="_blank", чтобы увеличить различие. В данном примере используется цепочка вызовов, описанная ниже.
jQuery('blockquote').each(function(el) { alert(jQuery(this).text()) });
Для каждого тега blockquote на странице выводит сообщение (alert) с его текстовым содержанием (включая HTML-теги).
• jQuery('a').html('Нажми здесь!');
Заменяет весь текст в ссылках на странице призывом «Нажми здесь!».
Ниже несколько примеров методов, которые возвращают значение от первого элемента, найденного по шаблону:
• var width = jQuery('div').width();
Какая ширина у первого div на странице?
var src = jQuery('img').attr('src');
Какое значение у атрибута src у первой картинки на странице?
var color = jQuery('h1').css('color');
Какой цвет у первого h1?

Отметим удобную симметрию таких методов: они используются как для выставления атрибутов (когда принимают 2 аргумента или у передаваемого объекта несколько свойств), так и для прочтения значений этих атрибутов (если передается только один аргумент). Такая симметрия используется во всей библиотеке jQuery, что очень сильно облегчает запоминание API.
Также есть несколько методов, которые изменяют весь набор найденных элементов. Многие из них также обеспечивают перемещение по DOM-дереву:

jQuery('div').not('[@id]')
Возвращает все div, у которых нет атрибута id.
jQuery('h2').parent()
Возвращает все элементы, которые являются непосредственными родителями h2.
jQuery('blockquote').children()
Возвращает все элементы, вложенные в blockquote.
jQuery('p').eq(4).next()
Находит пятый параграф на странице, потом находит следующий элемент (т.е. непосредственного соседа справа).
jQuery('input:text:first').parents('form')
Находит родительский элемент для формы, которая содержит первое поле input type="text" на странице. Опциональным параметром для parents() является другой селектор.

Цепочки вызовов
Команда разработчиков jQuery часто гордятся поддержкой в этой библиотеке цепочки вызовов, доходя до заявлений типа «jQuery создана для того, чтобы изменить ваш стиль программирования на JavaScript» прямо на главной странице. Эту технику находят скорее боковым ответвлением, чем дорогой в будущее, но вы можете использовать jQuery, избежав длинных цепочек вызовов.
Цепочки можно использовать для нескольких интересных трюков. В дополнение к использованию набора DOM-выборок вы можете применить jQuery-метод end() для перемещения по стеку объектов и выхода из текущего контекста. Это немного сложно объяснить, но когда вы используете метод, который изменяет текущий (объектный) контекст (например, children() или filter()), вы можете использовать end() чуть позже, чтобы вернуться к предыдущей выборке. Jesse Skinner приводит хороший пример использования этой возможности в своем учебнике Делаем разработку на AJAX проще с jQuery:

$('form#login')
    // прячем внутри формы все label с классом optional
    .find('label.optional').hide().end()
    // добавляем красную границу ко всем полям типа password в форме
    .find('input:password').css('border', '1px solid red').end()
    // добавляем обработчик на событие submit для формы
    .submit(function(){
        return confirm('Вы действительно хотите отправить данные?');
    });


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

Манипулируем с DOM
В jQuery имеется несколько способов для объемных манипуляций с DOM. Первый является несколько неожиданным: функция jQuery может принимать в качестве аргумента кусок HTML-кода, который преобразуется в DOM-элемент (фактически, это просто строка):
var div = jQuery('
Some text
');
Можно использовать цепочку вызовов, чтобы добавить атрибуты к div, как только он был создан:
var div = jQuery('<div>Some text</div>').addClass('inserted').attr('id', 'foo');
Теперь добавим его к тегу body:
div.appendTo(document.body)
Или вставим его, используя селектор, в имеющийся код:
div.prependTo('div#primary')

Перехватываем события
Все JavaScript-библиотеки нуждаются в методах для обработки событий, и jQuery не является исключением. Как и в случае attr() и css(), методы для событий могут служить двум целям: их вызов с функцией в качестве аргумента назначает обработчик события, вызов без аргумента эмулирует возникновение этого события:
jQuery('p').click(function() { jQuery(this).css('background-color', 'red'); });
Выставляем для всех параграфов обработчик клика мыши, по которому они становятся красными.
jQuery('p:first').click()
Эмулируем клик для первого параграфа на странице.
Похожие функции используются для других событий браузера: mouseover, keyup и т.д. Следует заметить, что при вызове обработчика событий ключевое слово this ссылается на элемент, который это событие вызвал; использование jQuery(this) является расхожим приемом, чтобы вызвать методы jQuery для этого элемента.
Пара функций, относящихся к событиям, заслуживает отдельного упоминания:
jQuery('a').hover(function() {
    jQuery(this).css('background-color', 'orange');
}, function() {
    jQuery(this).css('background-color', 'white');
});

hover() является сокращением для сразу двух событий: onmouseover и onmouseout.
jQuery('p').one('click', function() { alert(jQuery(this).html()); });
one() выставляет обработчик событий, который будет удален после первого своего вызова. В вышеприведенном примере всем параграфы должны сообщить (alert) свое содержание после первого клика по ним.
jQuery также поддерживает собственные события через методы bind() и trigger() (подобные click()). Собственные события могут принимать аргументы, передаваемые при помощи массива в вызове trigger():
jQuery(document).bind('stuffHappened', function(event, msg) {
    alert('Что прозошло: ' + msg);
});
jQuery(document).trigger('stuffHappened', ['Привет!']);


Ненавязчивое (unobtrusive) программирование
Лучшие веб-приложения — это те, которые могут функционировать и при отключенных скриптах, и лучшим методом для достижения этой цели будет ненавязчивый JavaScript, когда события назначаются элементам только после того, как вся HTML-страница у пользователя загрузится (для более подробной информации можно ознакомиться с ненавязчивым программированием и Hijax).
В jQuery присутствует замечательная поддержка этого подхода. Во-первых, парадигма селекторов для выбора узла является основополагающей как для jQuery, так и для ненавязчивого программирования в целом. Во-вторых, jQuery обеспечивает решения для проблемы window.onload, основанной на исследованиях Dean Edwards по поводу работы события "DOM loaded" для различных браузеров. Вы можете выставить функцию-обработчик тогда, когда DOM уже будет к ней готов:

jQuery(document).ready(function() {
    alert('DOM готов!');
});


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

jQuery(function() {
    alert('DOM готов!');
});


jQuery и AJAX
У jQuery лучший API для работы с AJAX, который я когда-либо видел в больших библиотеках. Наиболее простая форма AJAX-вызова выглядит следующим образом:
jQuery('div#intro').load('/some/fragment.html');

Он выполнит GET-запрос к /some/fragment.html и вставит в div#intro HTML-код, который получит.
Что если требуется что-то более сложное, например, вывести индикатор AJAX-загрузки? jQuery предоставляет набор собственных событий (ajaxStart, ajaxComplete, 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 занимает всего 20 КБ, и даже еще меньше, если применить архивирование (.gz). Дополнительная функциональность, выходящая за пределы это поставки, может быть организована с помощью расширений, которые могут (и так и делают) добавить новые методы к существующему объекту jQuery. При желании можно выполнить что-то вроде этого:

jQuery('p').bounceAroundTheScreenAndTurnGreen();

Механизм расширений в jQuery обеспечивает задокументированные методы для их добавления в систему. Простота и удобство их использования привлекли большое сообщество авторов таких расширений; справочник расширений насчитывает уже более ста примеров.
Еще одной приятной особенностью является возможность добавлять собственные селекторы так же, как и собственные методы. Расширение moreSelectors добавляет методы типа div:color(red), который, например, выбирает все div с красным текстом.

В качестве заключения
Здесь высказано достаточно фактов для положительного заключения по поводу jQuery, что она не является очередной библиотекой. В ней заложена масса интересных идей, которые способны удивить даже достаточно опытных JavaScript-программистов и научить их чему-то новому. Даже если вы не будете использовать ее в своей работе, стоит посвятить некоторое время и исследовать «экосистему» jQuery.

Все права на данную статью принадлежат Интернет-студии "Анор"
Добавить комментарий
Отображение комментариев: Древовидное | Плоское
NO USERPIC

avsv

Очень замечательная статья! СУПЕР! СУПЕР! СУПЕР! Всё прям сейчас же засяду изучать jQuery =)
16.04.2008, 23:14
Ответить
NO USERPIC

avsv

??? Люди HELP кто может
У меня возник небольшой вопрос, если кто поможет буду очень признателен. JS знаю совсем плохо, сам ничего писать на нём не умею, а вот разобраться в чужом коде могу уверенно.
Суть задачи, имеется:
- PHP
- MySQL
- JavaScript (jQwerty, AJax)

Php: скрипт предназначен для FTP поиска, страницу автора к сожалению не помню, называется "FtpSearch 2.0" - он грузит из БД список серверов, составляет Карту (Файлы & Директории) и загоняет это обратно в БД. Вопрос вобщем такой: как с помощью AJax можно отображать процесс индексации в реальном времени, не прерывая её.
Думаю в любой локалке нужен такой вот полезный скриптик, очень надеюсь на помощь ...
16.04.2008, 23:24
Ответить

bur

Самое сложное в вашей задаче - посчитать процент индексации. Понятно, что это нужно делать на сервере с помощью php-mysql.
Возможно ваша программа имеет встроенные методы для получения таких данных. Если нет - то AJAX здесь не поможет.
Если процент определять можно, то с помощью простого ajax-запроса с какой-то периодичностью (например, раз в секунду) дергайте
php-скрипт, который отдает численное значение (от 0 до 100 к примеру).

Итого: для вашей задачи необходимо на первом этапе решить проблему подсчета процента загрузки.
Остальное, в том числе ajax-запрос дело совсем не трудное :)
17.04.2008, 00:02
Ответить

kolka

Меня, лично, эта статья очень заинтересовала. Большое спасибо автору! Много для себя подчеркнул. Может автор подскажет книги или где можно ещё больше найти материала по jQuery на русском ? Спасибо.
20.06.2008, 13:55
Ответить
NO USERPIC

Octane

jQuery('p#intro')

В этом случае будет получена коллекция всех элементов &lt;p&gt; и вней будет найден один единственный &lt;p&gt; с id=&quot;intro&quot;, т. е. сначала выполняется метод document.getElementsByTagName('p'), а затем в этой коллекции идет поиск по атрибуту id.
Если написать так:
jQuery('#intro')

то сработает сразу метод document.getElementById('intro'). Помоему так рациональнее :) хотя может быть jQuery уже умеет оптимизировать такие вещи?
22.06.2008, 15:43
Ответить
NO USERPIC

rgbeast

Запрос jQuery('#intro') должен работать быстрее, но он не эквивалентен jQuery('p#intro'), так как возвращает не только элементы <p>. Чтобы оптимизировать последний, потребуется знать заранее чего в документе меньше - параграфов или элементов с id="intro", то есть некоторая специальная индексация документа. Вряд ли jQuery это делает.
22.06.2008, 20:58
Ответить
NO USERPIC

Octane

знать заранее чего в документе меньше - параграфов или элементов с id="intro"
Да? а я всегда почемуто думал, что идентификатор должен быть уникальным...
22.06.2008, 22:12
Ответить
NO USERPIC

rgbeast

Прошу прощения, перепутал с именем класса. По логике, jQuery должен выполнять запрос jQuery('p#intro') начиная с конца - выполнять getElementById('intro'), а затем проверять параграф ли это. Похоже, jQuery так и поступает: Например, в файле http://jqueryjs.googlecode.com/files/jquery-1.2.6.js есть строчки (1579-1592):
                    // Try to do a global search by ID, where we can
                    if ( m[1] == "#" && elem && elem.getElementById && !jQuery.isXMLDoc(elem) ) {
                        // Optimization for HTML document case
                        var oid = elem.getElementById(m[2]);
                        .....
                        .....
                        // Do a quick check for node name (where applicable) so
                        // that div#foo searches will be really fast
                        ret = r = oid && (!m[3] || jQuery.nodeName(oid, m[3])) ? [oid] : [];
22.06.2008, 23:03
Ответить
NO USERPIC

Octane

Отлично, наверно это появилось в новых версиях, в некоторых статьях по jQuery заостряют внимание на этом моменте, тогда разница в выражениях $('#intro') и $('p#intro') будет в том, что во втором случае результат будет возвращен если элемент с таким идентификатором является параграфом.
22.06.2008, 23:42
Ответить
NO USERPIC

Iliya Tretyakov

опечатка
var div = jQuery('<br />Some text<br />')
надо
var div = jQuery('<div>Some text</div>')
24.12.2008, 09:42
Ответить

bur

Спасибо, зафиксили.
24.12.2008, 12:09
Ответить
NO USERPIC

eap1985

Ещё один простой способ ajax в jquery
ajax = $.ajax({url: "2.php", async: false }).responseText;
Александр
09.09.2009, 17:48
Ответить

ecolora

Такая проблема. Допустим мы имеем в коде несколько библиотек jQuery разной версии. С какой будет работать наш скрипт? И тут даже noConfilct не поможет. Да он вернет переменную, но при обращении к jQuery в любом месте кода, какую библиотеку какой версии вызовет браузер?
Проблема особенно остро встает на сайтах, заточенных под версию 1.2.6, в частности и если на этот сайт "прикрутить" более новую версию, например 1.7.
Как мне вызвать библиотеку jQuery таким образом, чтобы все существующие скрипты не могли к ней обратиться, условно говоря, её не видели, а вот я при желании мог её вызвать и выполнить?
Мысль понятна?
10.11.2011, 12:45
Ответить
NO USERPIC

rgbeast

Если не использовать noConflict, то код будет обращаться к последней загруженной версии. Предпоследняя будет сохранена в _$. Ответ на ваш вопрос дан на форуме jquery: http://forum.jquery.com/topic/multiple-versions-of-jquery-on-the-same-page

Следующий код загрузит jquery-1.3.2 и сохранит его объект в переменную, при этом все, кто обращается не через данную переменную, будут использовать загруженную ранее версию.
<script src='jquery-1.3.2.js'></script>
<script>
var jq132 = jQuery.noConflict();
</script>
10.11.2011, 20:52
Ответить
Добавить комментарий
Отображение комментариев: Древовидное | Плоское
© 2008—2024 webew.ru, связаться: x собака webew.ru
Сайт использует Flede и соответствует стандартам WAI-WCAG 1.0 на уровне A.
Rambler's Top100

Реклама: