Некоторые скрытые особенности jQuery

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

1. Рассмотрим jQuery поближе!

Что происходит, когда Вы вызывате 'jQuery'?

Функция jQuery сама по себе очень проста:

 
jQuery = function (selector, context) {
    // Объект jQuery только инициирует конструктор
    return new jQuery.fn.init(selector, context);
};

Под этой оболочкой, функция jQuery просто возвращает присвоенный объект jQuery — то есть экземпляр конструктора 'jQuery.fn.init'.

Очень полезно знать, что каждый раз, когда мы вызываем 'jQuery', в действительности создается уникальный объект с набором свойств. jQuery предоставляет Вам объект, который может быть обработан как массив. Каждый Ваш элемент (все вместе они обычно называются "коллекцией") имеет ссылку в виде числового индекса, так же как и в массиве. jQuery также придает объекту свойство 'length', что похоже на массив. Такой подход открывает мир возможностей. Это означает, что мы можем использовать некоторую функциональность 'Array.prototype'. Метод jQuery 'slice' является хорошим примером такого использования:

 
/* ... jQuery.fn.extend({ ... */
slice: function() {
    return this.pushStack(
        Array.prototype.slice.apply( this, arguments ),
        "slice",
        Array.prototype.slice.call(arguments).join(",")
    );
},
/* ... */

Оригинальный метод 'slice' не беспокоится о том, что 'this' не является в действительности массивом – он работает с тем, что имеет свойство 'length' и индексы [0], [1], [2] и т.д.

Другие интересные свойства объекта jQuery — '.selector' и '.context'. В большинстве случаев они отражают аргументы, которые Вы передаете в 'jQuery(…)'.

 
var jqObject = jQuery('a');
jqObject.selector; // => "a"

Так же нужно отметить, что jQuery иногда возвращает новый экземпляр объекта для дальнейшей работы. Если Вы вызываете метод, который меняет коллекцию каким-либо образом, например '.parents()', то jQuery не будет модифицировать текущий объект. Он просто передаст Вам новый экземпляр:

 
var originalObject = jQuery('a');
var anotherObject = originalObject.parents();
 
originalObject === anotherObject; // => false

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

2. Бутербродное создание элементов

Центральное свойство DOM jQuery - это синтаксис создания элементов. Версия 1.4 имеет новый способ для того, чтобы создавать Ваши элементы быстро и кратко:

 
var myDiv = jQuery('<div/>', {
    id: 'my-new-element',
    class: 'foo',
    css: {
        color: 'red',
        backgrondColor: '#FFF',
        border: '1px solid #CCC'
    },
    click: function() {
        alert('Clicked!');
    },
    html: jQuery('<a/>', {
        href: '#',
        click: function() {
            // Выполняем какие-то операции
            return false;
        }
    })
});

Вы можете передать второй аргумент функции jQuery, когда создаете новый элемент — объект, который Вы передаете, в большинстве будет действовать так, как будто Вы его передали методу'.attr(…)'. Однако jQuery устанавливает соотвествие некоторых свойств своим собственным методам, например, свойство 'click' соответствует методу jQuery 'click' (который привязан к обработчку события 'click'), а 'css' соответствует методу jQuery 'css', и т.д..

Для того, чтобы проверить, какие свойства соответствуют методам jQuery, откройте консоль и наберите 'jQuery.attrFn'.

3. Делайте ввод последовательным

jQuery имеет метод, который Вы можете использовать для преобразования ввода к последовательному виду в рамках одной или нескольких форм. Такие действия полезны, когда происходит передача данных с помощью XHR ("Ajax"). Данная функция присутствует в jQuery уже давно, о ней не так часто упоминается, и многие разработчики ее не используют. Предача всей формы целиком через Ajax с использованием jQuery не может быть простым процессом:

 
var myForm = $('#my-form');
jQuery.post('submit.php', myForm.serialize(), function(){
    alert('Data has been sent!');
});

jQuery также имеет метод 'serializeArray', который разработан для использования с множественными формами, и функцию 'param' (в пространстве имен jQuery), которая получает обычный объект и преобразует его в строку запроса:

 
var data = {
    name: 'Joe',
    age: 44,
    profession: 'Web Developer'
};
 
jQuery.param(data); // => "name=Joe&age=44&profession=Web+Developer"

4. Анимируем все подряд

Метод jQuery 'animate' - вероятно самый гибкий метод jQuery. Его можно использовать для анимирования чего угодно, не только свойств CSS, но и элементов DOM. Пример того, как можно использовать 'animate':

 
jQuery('#box').animate({
    left: 300,
    top: 300
});

Когда Вы задаете свойство для анимации(например, 'top'), jQuery проверяет, анимируется ли что-то со свойствами стиля ('element.style'), а также проверяет, определено ли заданное свойство ('top') в 'style' — если нет, то jQuery просто обновляет 'top' на самом элементе. Пример:

 
jQuery('#box').animate({
    top: 123,
    foo: 456
});

'top' - это действительное свойство CSS, и jQuery обновит 'element.style.top'. Но 'foo' не является свойством CSS, и jQuery просто обновит 'element.foo'.

Мы можем использовать описанное для наших целей. Например, Вы хотите анимировать квадрат в пространстве изображения. Сначала определим простую конструкцию и метод 'draw', который будет вызываться на каждом шаге анимации:

 
function Square(cnvs, width, height, color) {
 
    this.x = 0;
    this.y = 0;
    this.width = width;
    this.height = height;
    this.color = color;
 
    this.cHeight = cnvs.height;
    this.cWidth = cnvs.width;
    this.cntxt = cnvs.getContext('2d');
 
}
 
Square.prototype.draw = function() {
 
    this.cntxt.clearRect(0, 0, this.cWidth, this.cHeight);
    this.cntxt.fillStyle = this.color;
    this.cntxt.fillRect(this.x, this.y, this.width, this.height);
 
};

Мы создали конструктор нашего 'Square', и один из его методов. Создание пространства изображения и анимирование выполняется просто::

 
// Создаем элемент <canvas/>
var canvas = $('<canvas/>').appendTo('body')[0];
canvas.height = 400;
canvas.width = 600;
 
// Создаем объект Square
var square = new Square(canvas, 70, 70, 'rgb(255,0,0)');
 
jQuery(square).animate({
    x: 300,
    y: 200
}, {
    // 'draw' следует вызывать на каждом шаге анимации

    step: jQuery.proxy(square, 'draw'),
    duration: 1000
});

Это очень простой эффект, но он ясно демонстрирует возможности.

5. jQuery.ajax возвращает объект XHR

Все функции jQuery Ajax ('jQuery.ajax', 'jQuery.get', 'jQuery.post') возвращают объект 'XMLHttpRequest', который Вы можете использовать для выполнения последующих операций над любым запросом. Например:

 
var curRequest;
 
jQuery('button.makeRequest').click(function(){
    curRequest = jQuery.get('foo.php', function(response){
        alert('Data: ' + response.responseText);
    });
});
 
jQuery('button.cancelRequest').click(function(){
    if (curRequest) {
        curRequest.abort(); // abort()- метод XMLHttpRequest
    }
});

Здесь мы делаем запрос, когда нажимается кнопка 'makeRequest'. А при нажатии на кнопку 'cancelRequest' происходит сборос текущего активного запроса.

Также данную особенность можно использовать для синхронизации запросов:

 
var myRequest = jQuery.ajax({
    url: 'foo.txt',
    async: false
});
 
console.log(myRequest.responseText);

6. Очередь пользователя

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

 
jQuery('a').hover(function(){
    jQuery(this).animate({paddingLeft:'+=15px'});
}, function(){
    jQuery(this).animate({paddingLeft:'-=15px'});
});

Если быстро провести мышкой по ссылкам несколько раз, то анимации станут в очередь и будут выполняться одна за другой. Можно воспользоваться страницой http://jsbin.com/aqaku

Метод 'queue' по сопособу вызова похож на хорошо известный метод 'each'. Вы выполняете функцию, которая будет вызвана для каждого элемента в коллекции:

 
jQuery('a').queue(function(){
    jQuery(this).addClass('all-done').dequeue();
});

Передача функции методу 'queue' приводит к тому, что функция добавляется к очереди 'fx', которая используется всеми анимациями, выполняемыми jQuery. Таким образом, данная функция не будет вызвана до тех пор, пока все текущии анимации на каждом элементе коллекции (в случае нашего примера - для всех ссылок) не будут завершены.

Отметим, что мы добавили класс 'all-done' в функцию нашего примера. Данный класс будет добавлен только тогда, когда все текущие анимации будут завершены. Также вызывается метод 'dequeue'. Это очень важно, псокольку позволяет jQuery продолжать выполнение очереди (то есть, данное действие сообщает jQuery о том, что Вы завершили то, что делали). jQuery 1.4 имеет другой способ для продолжения выполнения очереди. Вместо вызова метода 'dequeue' можно просто вызвать первый аргумент, переданный Вашей функции:

 
jQuery('a').queue(function(nextItemInQueue){
    // Продолжаем выполнение очереди:
    nextItemInQueue();
});

Эта операция делает то же самое, хотя она и значительно более удобна в использовании, так как может быть вызвана где угодно в Вашей функции, даже в мешанине завершающих действий (что обычно приводит к разрушению 'this' ). Конечно, для версий jQuery до 1.4 Вам следует сохранять ссылку на 'this', но это может быть очень утомительным процессом.

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

 
jQuery('a').queue('customQueueName', function(){
    // Делаем что-то
    jQuery(this).dequeue('customQueueName');
});

Отметим также, так как мы не используем очередь 'fx' , то мы должны передать имя нашей очереди методу 'dequeue', для того, чтобы позволить jQuery продолжать выполнение нашей очереди.

7. Пространство имен события

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

Чтобы добавить пространство имен при регистрации обработчика события, просто добавьте к имени события суффикс, который будет указывать на область действия (например, '.fooPlugin'):

 
jQuery.fn.foo = function() {
 
    this.bind('click.fooPlugin', function() {
        // Какие-то операции
    });
 
    this.bind('mouseover.fooPlugin', function() {
        // Какие-то операции
    });
 
    return this;
};
 
// Используем плагин:
jQuery('a').foo();
 
// Отключаем его обработчики событий:
jQuery('a').unbind('.fooPlugin');

Передача названия пространства имен методу 'unbind' приведет к отвязыванию всех обработчиков событий в этом пространстве имен.

Данный урок подготовлен для вас командой сайта ruseller.com
Источник урока: www.net.tutsplus.com
Перевел: Сергей Фастунов
Урок создан: 29 Июня 2010
Просмотров: 27662
Правила перепечатки


5 последних уроков рубрики "jQuery"

или авторизуйтесь, чтобы добавлять комментарии, оценивать уроки и сохранять их в личном кабинете
  • 29 Июня 2010 14:43
    FeroDaR
    ого! круто ._.
  • 29 Июня 2010 15:52
    НеБот
    > jQuery.ajax возвращает объект XHR Или, если это ослик, то ActiveX. Всё у M$ не как у людей...
  • 29 Июня 2010 17:24
    kiesy
    вы немного опоздали с переводом http://vredniy.ru/2010/03/jquery-for-beginners-part4/
  • 30 Июня 2010 10:49
    FeroDaR
    kiesy, и что?
  • 1 Августа 2010 14:44
    Николай
    хороший урок
  • 1 Августа 2010 14:44
    Николай
    класс
  • 22 Сентября 2010 22:49
    Андрей
    нужно, но, блин, не все толком понял...
^ Наверх ^