Pull to refresh

Нововведения в jQuery 1.6

jQuery *
jquery
Совсем недавно (3 мая) был зарелизен jQuery 1.6 и вот что нового появилось в этой js-библиотеке давайте и посмотрим.

Самое «веселое» то, что в новом релизе есть важные изменения, которые несовместимы с предыдущими версиями jQuery. И в результате при переходе на новую версию, вполне возможно, что придётся просматривать и изменять уже существующий код.

Критические изменения


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

Доступ к данным в data-атрибутах

Теперь доступ к значениям в этих атрибутах соответствует спецификации W3C HTML5 spec, т.е. ключи надо передавать в camel-case формате.
<div id="div1" data-test-value="123"></div>

Для jQuery 1.5 писали так:
var tv = $('#div1').data('test-value'); // => 123
// или так
var d = $('#div1').data(); // => { "test-value": 123 }
tv = d['test-value']; // => 123

Теперь для jQuery 1.6 надо писать так:
var tv = $('#div1').data('testValue'); // => 123
// или так
var d = $('#div1').data(); // => { "testValue": 123 }
tv = d.testValue; // => 123


.prop(), .removeProp() и .attr()

Также теперь отделены свойства элементов от их атрибутов. Для доступа к атрибутам остался метод .attr(), а для доступа к свойствам элемента, которые могут меняться динамически (значения атрибутов при этом не меняются), теперь нужно делать через .prop(). Самым простым примером может быть поведение <input type="checkbox" />: в 1.5 вызов .attr('checked') возвращал true/false в зависимости от установки флага, в версии же 1.6 .attr('checked') вернёт строковое значение, записанное в атрибут, или undefined, если атрибут отсутствует, а состояние флага нужно получать через .prop('checked').
Поиграться с примерами можно тут: на 1.5 jsfiddle.net/dV27a/1, на 1.6 jsfiddle.net/9zEC9/1
.removeProp() следует использовать с особой осторожностью, т.к. чревато глюками в некоторых браузерах.
Во втором примере можно наблюдать глюк в Google Chrome, и это глюк именно браузера — воспроизводится и без jQuery. Глюк в следующем: если у элемента <input type="checkbox" /> через его js-объектную модель устанавливать свойство checked — то флаг изначально меняется, но если удалить это свойство так delete cb.checked, то после этого изменение свойства не приводит к изменению состояния флага.

В связи с описанным выше, появились некоторые изменения для булевых атрибутов (таких как checked, selected и подобных), теперь .attr('checked', true/false) добавляет или удаляет указанный атрибут (а мы помним, что теперь эта функция работает именно с атрибутом, а не со свойством объекта).

Некритические изменения


Расширяемость .attr() и .val()


В новой версии была добавлена возможность влиять на работу функций .attr() через объект jQuery.attrHooks и на функцию .val() через объект jQuery.valHooks. Например:
jQuery.attrHooks.selected = {
    set: function( elem, value ) {
        if ( value === false ) {
            jQuery.removeAttr(elem, “selected”);
            return value;
        }
    }
};


jQuery.map(Object)


Теперь функция jQuery.map() может принимать первым аргументом не только массив, но и объект, однако возвращать будет массив значений в любом случае.
$.map({ f: 1, s: 2 }, function(v, k) { return ++v; }); // => [ 2, 3 ]


Зависимое изменение CSS


Разработчики добавили возможность изменения css-свойств элементов функцией .css() в зависимости от их значения с помощью инструкций "+=" и "-=", как это сделано в .animate().
$("#item").css("left", "+=10px");


Deferred-объекты


Были внесены улучшения и в deferred-объекты, которые добавлены в 1.5 (тем, кто про них ещё не знает, советую почитать jQuery Deferred Object (подробное описание))

deferred.always()

Когда нужно, чтобы некоторый обработчик вызывался при любом исходе раньше приходилось писать deferred.then(handler, handler), а теперь можно написать deferred.always(handler)

deferred.pipe()

Это новый метод и решает сразу несколько проблем, во-первых с помощью него можно создавать фильтры значений, передаваемых в обработчики параметрами, во-вторых можно строить цепочки из отложенных-заданий (например, асинхронных запросов — эта тема поднималась в комментариях к моей предыдущей статье и вот разработчики предоставили решение этой проблемы).
Пример фильтра (для deferred.reject — аналогично), во второй обработчик первым и единственным параметром попадает значение, которое вернёт первый обработчик.
var defer = $.Deferred(),
    filtered = defer.pipe(function( value ) {
        return value * 2;
    });
defer.resolve( 5 );
filtered.done(function( value ) {
    alert( "Value is ( 2*5 = ) 10: " + value ); // value = 10
});

Запустить: jsfiddle.net/txzPj

Пример цепочки асинхронных запросов, во второй обработчик будут переданы параметры, с которыми будет завершен второй deferred-объект.
var request = $.ajax( '/echo/json/', { dataType: "json", type: 'post', data: { json: '{ "test": 8 }' }, delay: 3 } ),
    chained = request.pipe(function( data ) {
        console.log(data);
        alert('first response');
        return $.ajax( '/echo/json/', { type: 'post', data: { delay: 3, json: '' + data.test } } );
    });

chained.done(function( data ) {
    console.log(data);
    alert('second response');
});

Запустить: jsfiddle.net/5gfS8

Анимация


Кроме улучшения в самом процессе анимирования, в версии 1.6 можно использовать deferred-объекты, завязанные на анимацию. Нет, метод .animate() (и его сокращения .fadeOut(), slideUp() и пр.) не стали возвращать deferred, вместо этого появилась возможность использовать любой jquery-объект в качестве параметра функции $.when(), и если среди выбранных элементов есть какие-то с анимацией, то полученный deferred-объект будет завершён после завершения всей анимации.
$(".elements").fadeOut();

$.when($(".elements")).done(function(elements) {
    // здесь для всех ".elements" анимация завершена
});


jQuery.holdReady()


Этот метод позволяет приостановить выполнение обработчиков события ready, использоваться он будет преимущественно разработчиками плагинов (по крайней мере, так планируют авторы jQuery).
jQuery.holdReady( true ); // приостановили выполнение обработчиков
// запустили какой-то код, например асинхронный запрос
// и когда наш асинхронный запрос выполнился, можем разрешить выполнение остальных обработчиков
jQuery.holdReady( false );


Селектор ":focus"


Теперь стало совсем просто найти в документе элемент, на котором установлен фокус.

Дополнительные возможности в функциях обхода DOM


В новой версии добавили возможность передавать аргументом в функции .find(), .closest() и .is() ещё и jquery-объекты, наконец-то…



Текст этой статьи — это вольный пересказ blog.jquery.com/2011/05/03/jquery-16-released (не перевод, хотя и очень близко к тексту).
Tags: jqueryjquery 1.6
Hubs: jQuery
Total votes 157: ↑156 and ↓1 +155
Comments 46
Comments Comments 46