Сегодня (по Москве почти в полночь) официально объявлено о выпуске jQuery версии 1.4. Выход новой версии, как и в прошлом году, приурочен к дню рождения библиотеки, которой исполнилось уже 4 года. Собственно, интересующиеся этой тематикой уже могли ознакомиться с релизами jQuery 1.4 Alpha 1 от 4 декабря 2009 года и jQuery 1.4 Alpha 2 от 18 декабря 2009 года. А 12 января появился релиз-кандидат jQuery 1.4rc1. Подробное знакомство с новшествами еще впереди, но я не мог не дать краткий обзор изменений и новых возможностей, которые появились в очередной версии. Начнем знакомство?

Метод .addClass(className) теперь может принимать в качестве аргумента не только имя класса (или классов), но и функцию .addClass(function), которая должна возвратить один или более имен классов, которые должны быть добавлены элементу. Если имен классов более одного, они должны быть разделены пробелами. На примере:

$('ul li:last').addClass(function() {
    return 'item-' + $(this).index();
});

Аналогичные изменения претерпели методы .removeClass(className) и .toggleClass(className), которые также теперь могут принимать функцию в качестве аргумента.

Похожие изменения внесены в методы .after(content), .before(content), .append(content) и .prepend(content). Все эти методы начиная с версии 1.4 могут принимать в качестве аргумента функцию, которая должна возвращать строку html-кода.

Аналогичным образом дополнены методы .html(htmlString) и .text(textString). Если до версии 1.4 эти методы принимали аргументом соответственно строку html-кода и обычный текст, то теперь аргументом может быть также функция – .html(function) и .text(function). Функции должны возвращать соответственно html-код и текст.

Дополнен метод .val(). Теперь при установке нужного значения можно использовать не только собственно значение, но и функцию, которая должна возвращать требуемое значение.

Дополнен метод .css(). Если раньше для того, чтобы установить значение какого-либо css-свойства мы использовали .css(propertyName, value) или .css(map) для того, чтобы установить значения сразу нескольких css-свойств элемента, то теперь получили возможность использовать во втором аргументе функцию, возвращающую то значение, которое должно быть установлено этому css-свойству .css(propertyName, function).

Чтобы сохранить произвольные данные, связав их с выбранным элементом мы должны были передать методу .data(key, value) соответствующие пары ключ/значение. Теперь аргументом этого метода может быть и непосредственно объект .data(obj). Чтобы получить доступ к сохраненным данным требуется указать .data(key) имя под которым были сохранены эти данные. В дополнение к этому с версии 1.4 можно вызвать метод .data() без аргументов, и в этом случае данные будут возвращены в виде объекта.
Точно также теперь можно поступить и в том случае, если данные, связанные с элементом были сохранены в свойстве data объекта jQuery.

Начиная с версии 1.4 добавлены вспомогательные функции jQuery.isEmptyObject(object) – проверяет, является ли объект пустым (не содержащим свойств)

jQuery.isEmptyObject({}) // вернет true
jQuery.isEmptyObject({ foo: "bar" }) // вернет false

и jQuery.isObjectLiteral(object) – проверяет является ли он простым объектом (создан с помощью {} или new Object)

jQuery.isPlainObject({}) // true
jQuery.isObjectLiteral("test") // false

Добавлены методы .prevUntil([selector]), .nextUntil([selector]) и .parentsUntil([selector]). Первые два новых метода помогут выбрать все элементы соответственно перед и после, но при этом ДО элемента [selector] указанного в качестве аргумента метода. А метод .parentsUntil([selector]) поможет выбрать всех родителей, но также ДО элемента [selector] указанного в качестве аргумента.

Дополнены методы .wrap(wrappingElement), .wrapAll(wrappingElement) и .wrapInner(wrappingElement). Теперь в качестве аргумента этих методов можно использовать функцию, которая должна возвращать структуру в которую будет обернут каждый выбранный элемент (для wrap), все выбранные элементы (для wrapAll) или внутреннее содержимое выбранного элемента (для wrapInner). Также добавлен новый метод .unwrap(), название которого говорит само за себя – удаляет непосредственных родителей выбранных элементов, оставляя сами элементы без изменений.

Добавлен весьма полезный метод .delay(duration, [queueName]), которые позволяет установить таймер задержки выполнения следующего пункта очереди. На примере:

$('#foo').slideUp(300).delay(800).fadeIn(400);

Здесь метод fadeIn начнет выполняться только через 800 миллисекунд после того, как отработает метод slideUp.

Добавлен метод .detach([selector]), который похож на метод .remove() тем, что также удаляет выбранные элементы из DOM, но, в отличие от .remove() новый метод сохраняет данные, связанные с удаленными элементами, что можно использовать при возврате удаленных элементы обратно в DOM.

Добавлен метод .toArray(), который возвращает в виде массива все DOM-элементы, включенные в набор jQuery. Выполнив

alert($('li').toArray());

увидим что-то вроде

[<li id="foo">, <li id="bar">]

Дополнен метод .replaceWith(newContent) и теперь в качестве аргумента может использоваться функция, которая должна возвращать строку html-кода, которым должен быть заменен выбранный элемент.

Дополнен метод .add(), с помощью которого можно добавлять в существующий набор дополнительные элементы. Если до версии 1.4 в качестве аргумента можно было указать jQuery-селектор, элемент(или элементы) и фрагмент html-кода, то теперь появилась возможность после селектора указать второй аргумент – контекст, в котором будет производится поиск нужного элемента(ов).

Добавлены новые методы .focusin(handler(eventObject)) и .focusout(handler(eventObject)). Методы вызывают обработчики соответственно при получении и потере фокуса выбранным элементом. В качестве аргумента обработчик принимает объект события.

Добавлен метод .has(selector), с помощью которого можно проверить наличие элемента внутри другого элемента. Для разметки

<ul><li>Does the UL contain an LI?</li></ul>

выполним код

$("ul").append('<li>' +
($("ul").has("li").length ? "Yes" : "No") +
'</li>');

Такой код добавит в список элемент li с текстом Yes.

Дополнен метод .index(element) с помощью которого можно было узнать индекс DOM-элемента в наборе. Теперь может принимать в качестве аргумента селектор jQuery, а также может быть вызван без передачи аргумента. Довольно интересно, чтобы смотреть на примерах.

<ul>
  <li id="foo">foo</li>
  <li id="bar">bar</li>
  <li id="baz">baz</li>
</ul>

В качестве аргумента DOM-элемент:

var listItem = document.getElementById('bar');
alert('Index: ' + $('li').index(listItem));  // 1

В качестве аргумента объект jQuery:

var listItem = $('#bar');
alert('Index: ' + $('li').index(listItem)); // 1

И без передачи аргумента:

alert('Index: ' + $('#bar').index(); // 1

т.е. возвращается индекс (считаем от 0) элемента в наборе, в котором присутствуют все сестринские элементы этого уровня.

Дополнен метод .closest(selector), теперь вторым параметром можно передать контекст.

Добавлен новый метод .clearQueue([queueName]), который удаляет из очереди все функции, которые еще не были выполнены. Похож на .stop(true), однако есть отличия.

Дополнен метод .offset(), который позволяет получить координаты выбранного элемента относительно документа. Теперь координаты можно будет устанавливать с помощью передачи этому методу аргумента – .offset(coordinates). Здесь coordinates – объект, содержащий свойства top и left, значениями которых являются числовые значения новых координат. Также в качестве аргумента может выступать функция .offset(coordinates(index,coords)), которая в свою очередь принимает в качестве первого аргумента индекс элемента в наборе, а качестве второго – его новые координаты.

Изменения коснулись и функция jQuery(). Теперь при ее вызове без аргументов будет возвращен пустой набор.

Изменения во вспомогательной функции jQuery.param(obj), которая упорядочивает предоставленный объект или массив, представляя его в форме, пригодной для передачи в URL или Ajax-запросе. Начиная с версии 1.4 можно передавать второй параметр jQuery.param(obj, traditional), где traditional – логическое значение, которое устанавливается в true, если необходимо эмулировать поведение этой функции как в версиях ниже 1.4.

Новая вспомогательная функция jQuery.contains(container, contained), позволяющая проверить существование элемента DOM внутри другого элемента DOM. Здесь container – элемент DOM, который может содержать другой элемент DOM, а contained – элемент DOM, который может находится внутри. На примере:

// true
jQuery.contains(document.documentElement, document.body);
// false
jQuery.contains(document.body, document.documentElement);

Добавлена jQuery.noop() – функция, которая ничего не делает.

Новый метод jQuery.proxy(). Принимает пару аргументов, например так jQuery.proxy(function, scope), где function – функция, область видимости которой будет изменена, а scope – объект в который должна быть установлена область видимости функции. Грандиозно! Еще вариант – jQuery.proxy(scope, name), где scope – то же, а name – имя функции, область видимости которой будет изменена (должно быть свойством объекта ’scope’). На примере:

var obj = {
  name: "John",
  test: function() {
    alert( this.name );
    $("#test").unbind("click", obj.test);
  }
};
// 2-й вариант
$("#test").click( jQuery.proxy( obj, "test" ) );
// И так тоже работает:
// 1-й вариант
// $("#test").click( jQuery.proxy( obj.test, obj ) );

Обзор конечно получился краткий, несколько поспешный и насколько я уже понимаю с некоторыми неточностями (не по моей вине :) ), но для тех, кто хочет сам покопаться и разобраться повнимательнее – новый сайт API jQuery.

P.S. Поздравляю всех с наконец-то окончательно наступившим Новым Годом, jQuery – с четвертым Днем Рождения и выходом очередной версии, а себя – с Днем Рождения своего блога, которому исполнилось два года.

google.com bobrdobr.ru del.icio.us technorati.com linkstore.ru news2.ru rumarkz.ru memori.ru moemesto.ru