jQuery

Вышел релиз jQuery 1.6 с переписанным модулем атрибутов и некоторыми улучшениями производительности.

Подробнее о релизе jQuery 1.6

В кратце:

  • добавлены .prop(), .removeProp() которые вводят разделение понятий атрибутов и свойств DOM-элемента. Теперь, наконец, $('checkbox').attr('checked') будет возвращать пустую строку, т.к. будет искать "checked" атрибут элемента и это значение не поменяется, если чекбокс будет выбран. 
  • .data() метод будет генерировать объект с ключами camel-case формата, а не через тире.
  • улучшили скорость работы getter'ов/setter'ов .attr(), .val(), .data()

http://code.jquery.com/jquery-1.6.js
http://code.jquery.com/jquery-1.6.min.js

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

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

Доступ к данным в 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-объекты, наконец-то…