17 нововведений jQuery 3 и советы по их использованию

Прошло уже более 10 лет с того момента, как библиотека jQuery начала своё широкое распространение по Интернету, и она до сих пор пользуется большой популярностью. В июле 2015 года jQuery анонсировала альфа-версию 3.0 — крупнейшее обновление за долгие годы.

Текущая версия 3.1.1, вышедшая в сентябре 2016 года, исправила множество багов, добавила новые методы и удалила избыточные, также изменив поведение некоторых функций. Давайте разберемся в нововведениях, которые были представлены в этой версии.

Методы скрытия и отображения

Для лучшей совместимости с адаптивным дизайном jQuery3 была усовершенствована, получив возможность скрытия нескольких элементов. Тесты показали, что новая версия справляется с этим на 2% быстрее, чем предыдущая.

show/hide

Кроме того, методы .hide(), .show() и .toggle() будут ориентироваться на inline-стили. Эта особенность позволит корректно работать с функцией display, что позволит правилам CSS изменяться динамически в зависимости от таких событий, как изменение разрешения окна и ориентации экрана.

<script>
$( "#showr" ).click(function() {
  $( "div" ).first().show( "fast", function showNext() {
    $( this ).next( "div" ).show( "fast", showNext );
  });
});
 
$( "#hidr" ).click(function() {
  $( "div" ).hide( 1000 );
});
</script>

Методы wrapAll() и unwrap()

В jQuery 2 метод .wrapAll() при передаче функции в качестве аргумента вёл себя точно так же, как и метод .wrap(). Это изменили — теперь .wrapAll(function) вызывает функцию и использует строковое представление результата как обёртку коллекции.

$( "div" ).wrapAll(function( /* No index argument, since the function would be executed only once */ ) {
&nbsp;&nbsp;&nbsp;&nbsp;// context is equal to the first found element
&nbsp;&nbsp;&nbsp;&nbsp;return "<h4></h4>";
});

В jQuery 3 также появился опциональный параметр-селектор метода unwrap(). Это нововведение позволяет передавать методу строковое значение, которое содержит выражение селектора.

Полосы прокрутки высоты и ширины теперь учитываются

В jQuery 2 вызов $(window).width() возвращал ширину содержимого, не учитывая полосы прокрутки, добавленные браузером, когда содержимое превышало размеры элемента. Для того, чтобы предоставить возможность измерения, эквивалентную CSS-медиазапросу, $(window).outerWidth() и $(window).outerHeight() теперь возвращают ширину и длину с учётом полос прокрутки. Это эквивалентно свойству DOM window.innerWidth.

Поведение data()

В jQuery 3 поведение метода data() было немного изменено, чтобы он подходил под спецификации Dataset API. Теперь он переводит имена свойств в верблюжью нотацию.

var $elem = $('#container');
 
$elem.data({
   'custom-property': 'Hello World'
});
 
console.log($elem.data());

При использовании старой версии вы получите следующий результат:

{custom-property: "Hello World"}

В jQuery 3 вы получите:

{customProperty: "Hello World"}

Как вы заметили, название параметра переведено в верблюжью нотацию, в то время как в старых версиях параметр оставался в нижнем регистре с дефисом.

Поддержка SVG при операциях с классами

jQuery до сих пор не полностью поддерживает SVG, но методы наподобие .hasClass() или .addClass(), которые управляют CSS-классами, могут быть использованы для работы с SVG. Вы можете изменять или находить классы в SVG, затем применять стили к классам, используя CSS.

Фильтры скрытия и отображения

jQuery 3 изменяет смысл фильтров :visible и :hidden. Он воспринимает элементы как :visible, если у них есть хоть какие-то окна макета, включая те, которые имеют нулевую ширину и длину. Для примера, элемент br и строковые элементы без содержимого будут выделены фильтром :visible.

Если вы имеете следующую HTML-страницу:

<section></section>
<div></div>
<br />

и запускаете выражение:

console.log($('body :visible').length);

то в jQuery 2, вы получите результат 0, а в третьей версии результат будет равен 3.

jQuery больше не округляет параметры высоты и ширины

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

Например, у вас есть 3 элемента с шириной, равной одной третьей (33.333333%), внутри контейнера шириной 100px:

<div class="container">
   <div>Эта машина - </div>
   <div>черная</div>
   <div>Audi</div>
</div>

Если вы запросите ширину дочернего элемента:

$('.container div').width();

то получите значение 33.33333, что будет являться более точным результатом.

Дополнительный уровень защиты

Дополнительный уровень был добавлен для защиты от межсайтового скриптинга (XSS). Разработчикам теперь нужно уточнять dataType:”script” в опциях методов $.ajax() и $.get(). Это предотвращает возможность атак. Предоставляем пример кода:

$.ajax({
  accepts: {
    mynewcustomtype: 'application/abc-some-custom-type'
  },
  // how to deserialize a `mynewcustomtype`
  converters: {
    'text mynewcustomtype': function(result) {
      // do things
      return newresult;
    }
  },
 
  // Expect a `mynewcustomtype` back from server
  dataType: 'mynewcustomtype'
});

Неприменимый хеш

jQuery 3 возвращает синтаксическую ошибку, если строка селектора состоит лишь из хеша, вроде jQuery("#") или .find("#"). В старой версии $("#") возвращал пустое множество, а .find("#") — ошибку.

Новый метод для выделения строк

Новый метод jQuery.escapeSelector() позволяет вам выделить любую строку или символ, которые имеют определенное значение в CSS-селекторах.

Например, если элемент на странице имеет id “abc.xyz”, то он не может быть выбран методом $("abc.xyz"), т.к. селектор будет распознан как элемент с id “abc”, и классом “xyz”. Однако он может быть выбран новой функцией $("#" + $.escapeSelector("abc.xyz")).

Аргументы jQuery.when()

В jQuery 3 при добавлении методом then() аргумента к $.when(), он возвращает его promise-версию. Это расширяет возможности для ввода, включая промисы Bluebird и промисы ES6, что дает возможность писать более сложные асинхронные обратные вызовы.

$.when($.ajax("test.apx")).then(function(data,textStatus,jqHXR) {
 alert (jqHXR.status); //выводит 200
 });

Хеш в URL

Теперь функция jQuery.ajax() больше не удаляет хеш в URL, если он присутствует. Однако, вам придется удалять его вручную до отправки запроса, если сервер на другом конце соединения не может обработать URL с хешем.

Deferred-объекты совместимы с JS-промисами

Deferred’ы — это объекты которые можно соединять цепными обратными вызовами. jQuery 3 сделал их совместимыми с новыми стандартами Promises/A+. Также есть ключевое изменение в функции .then(). Любое исключение, выбрасываемое в рамках обратного вызова .then(), теперь конвертируется в отклоняемое значение. Непромисообразные значения, возвращенные обработчиком отклонений, меняются на выполняемые значения.

Устаревший deferred-метод:

$.ajax("/stat")
   .done(function(data) {
      whoops();
      // консоль выводит: "whoops is not a function"
      // больше не выполняется
   })
   .fail(function(arg) {
      // не выполняется 
   });

Новый стандарт поведения Promises/A+:

$.ajax("/stat")
   .then(function(data) {
      whoops();
      // консоль выводит "jQuery.Deferred exception: whoops is not a function"
      // больше не выполняется
   })
   .catch(function(arg) {
      // arg is an Error object - "whoops is not a function"
   });

Новый API для анимации

анимация

jQuery 3 использует API requestAnimationFrame() для работы с анимацией. Этот API воспроизводит анимации плавнее и быстрее, затрачивая меньше вычислительного времени. Он используется лишь в тех браузерах, которые поддерживают этот API. Для старых же браузеров, таких как Internet Explorer 9, jQuery использует старый API в качестве запасного варианта.

jQuery 3 работает в строгом режиме

Большинство браузеров, поддерживающих jQuery3, используют строгий режим (strict mode). Новая версия была создана с учётом это. Несмотря на то, что jQuery 3 была написана в строгом режиме, вашему коду не обязательно использовать его. Следовательно, вам не нужно переписывать уже существующий код, если вы желаете перейти на новую версию. Однако есть одно исключение: некоторые версии ASP.NET не совместимы из-за строгого режима.

Новая сигнатура методов get и post

jQuery получила новые сигнатуры сервисных функций $.get() и $.post() для единообразия с $.ajax().

$.get([settings])
$.post([settings])

Оператор цикла for…of

jQuery 3 поддерживает оператор цикла for..of, который имеется в спецификации ECMAScript 6. Это позволяет вам запускать цикл по итерируемым объектам, таким как Map, Set, Array и т.д.

Оператор цикла for..of может быть использован для замены синтаксической конструкции $.each( ). Предположим, что вы хотите применить имя к каждому вводимому элементу страницы.

Код на jQuery 2 выглядит так:

var $inputs = $('input');
 
for(var j = 0; j < $inputs.length; j++) {
   $inputs[j].id = 'input - ' + j;
  }

Но код на jQuery 3 будет иметь следующий вид:

var $inputs = $('input');
var j = 0; 
 
for(var input of $inputs) {
   input.id = 'input - ' + j++;
  }

Перевод статьи What’s New In jQuery 3 || 17 Added Features & How To Use Them