
Совсем недавно (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 (не перевод, хотя и очень близко к тексту).