Возможно вам больше не потребуется jQuery

alexei24/09/2019 - 09:35

С момента выпуска jQuery в 2006 году DOM и нативное API браузеров значительно улучшились. Статьи о том, что вполне можно обходиться без jQuery, выходят с 2013 года. Не хотелось бы пересказывать уже старые тезисы, но с тех пор в браузерной стране многое изменилось. Браузеры продолжают внедрять новые API-интерфейсы, которые избавляют от проблем при разработке без использования JavaScript библиотек, многие из которых напрямую скопированы из jQuery.

Давайте рассмотрим несколько новых ванильных альтернатив методам jQuery.

Удалить элемент со страницы

Помните безумно окольный способ, которым вы должны были удалить элемент со страницы в ванильном DOM? Тогда надо было создать весьма громоздкую конструкцию типа el.parentNode.removeChild(el);. Вот сравнение способа jQuery и нового улучшенного способа "из коробки".

jQuery:


var $elem = $(".someClass") //отобрать элемент 
$elem.remove(); //удалить элемент

Без jQuery:


var elem = document.querySelector(".someClass"); //отобрать элемент
elem.remove() //удалить элемент

Внимание! В этой статье мы будем предполагать, что $elem - набор элементов, выбранный jQuery, а elem является нативным элементом DOM, выбранным в JavaScript.

Добавить элемент

jQuery:


$elem.prepend($someOtherElem);

Без jQuery:


elem.prepend(someOtherElem);

Вставить элемент перед другим элементом

jQuery:


$elem.before($someOtherElem);

Без jQuery:


elem.before(someOtherElem);

Заменить элемент другим элементом

jQuery:


$elem.replaceWith($someOtherElem);

Без jQuery:


elem.replaceWith(someOtherElem);

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

jQuery:


$elem.closest("div");

Без jQuery:


elem.closest("div");

Поддержка браузерами методов манипуляции DOM

Эти методы в настоящее время довольно активно поддерживаются большинством браузерами.

Согласно данным с сайта Caniuse на сегодня мы имеем следующее положение дел. Число показывает версию браузера, начиная с которой поддерживается данные функции.

Настольные компьютеры:

ChromeOperaFirefoxIEEdgeSafari
544149Нет1710

Мобильные устройства:

iOS SafariOpera MobileOpera MiniAndroidAndroid ChromeAndroid Firefox
10.0-10.246Нет677567

Также на текущий момент эти методы реализованы в Edge.

Исчезновение элемента

jQuery:


$elem.fadeIn();

Написав собственный CSS, вы можете в большей степени контролировать анимацию элемента:


.thingy {
  display: none;
  opacity: 0;
  transition: .8s;
}

JavaScript:


elem.style.display = "block";
requestAnimationFrame(() => elem.style.opacity = 1);

Разовый вызов обработчика события

jQuery:


$elem.one("click", someFunc);

В прошлом при написании чистого JavaScript приходилось вызывать функцию removeEventListener внутри функции обратного вызова:


function dostuff() {
  alert("кое-что произошло");
  this.removeEventListener("click", dostuff);
}
var button = document.querySelector("button");
button.addEventListener("click", dostuff);

Теперь все намного чище. Возможно, вы видели третий необязательный параметр, иногда передаваемый в addEventListener. Это логическое значение, которое определяет тип события — захват или всплытие. Теперь же этот третий параметр также может быть объектом конфигурации:


elem.addEventListener('click', someFunc, { once: true, });

Если же вы все еще хотите использовать тип события захват, а также вызывать функцию обратного вызова только один раз, то вы можете указать это в объекте конфигурации:


elem.addEventListener('click', myClickHandler, {
  once: true,
  capture: true
});

Анимация

jQuery метод .animate() довольно ограничен.


$elem.animate({
  width: "70%",
  opacity: 0.4,
  marginLeft: "0.6in",
  fontSize: "3em",
  borderWidth: "10px"
}, 1500);

В документации говорится: "Все анимированные свойства должны быть анимированы по одному числовому значению, за исключением случаев, указанных ниже; большинство свойств, которые не являются числовыми, не могут быть анимированы с использованием базовых функций jQuery." Это делает невозможным какие-либо преобразования, и, например, для анимации цветов вам потребуется специальный плагин. Вам было бы намного проще с новым API веб-анимации.


var elem = document.querySelector('.animate-me');
elem.animate([
  { 
    transform: 'translateY(-1000px) scaleY(2.5) scaleX(.2)', 
    transformOrigin: '50% 0', 
    filter: 'blur(40px)', 
    opacity: 0 
  },
  { 
    transform: 'translateY(0) scaleY(1) scaleX(1)',
    transformOrigin: '50% 50%',
    filter: 'blur(0)',
    opacity: 1 
  }
], 1000);

Ajax

Еще одним важным достоинством фреймворка jQuery была работа с Ajax. jQuery отлично абстрагируется от уродства XMLHttpRequest:


$.ajax('https://some.url', {
  success: (data) => { /* делаем все, что нужно с данными */ }
});

Тем не менее, в настоящее время новый API выборки стал великолепной заменой XMLHttpRequest. К тому же он поддерживается всеми современными браузерами.


fetch('https://some.url')
  .then(response => response.json())
  .then(data => {
    // делаем все, что нужно с данными
  });

По общему признанию использование механизма выборки может быть немного сложнее, чем представлено в этом небольшом примере кода. Например, возвращаемое "обещание" Promise от fetch() не будет отклонено из-за ошибки HTTP. Тем не менее, данный API гораздо более универсален, чем что-либо построенное поверх XMLHttpRequest.

Если мы хотим простоты использования, есть более простой вариант, который приобрел популярность - но он не является родным для браузера, и это приводит нас к ...

Использование микробиблиотек

Axios - это популярная библиотека для Ajax. Это отличный пример микробиблиотеки - библиотеки, предназначенной только для одной цели. Хотя большинство библиотек не будут так хорошо тестироваться, как jQuery, они часто могут стать привлекательной альтернативой бегемоту jQuery.

(Почти) Все можно возместить

Итак, теперь вы знаете, что с DOM теперь приятно работать! Но, возможно, посмотрев на все эти новшества, вы только вздохнете и скажете: "Ну что ж, все это хорошо, но мне все равно нужно поддерживать IE 9, поэтому я лучше останусь с jQuery". Однако, в большинстве случаев не имеет значения, что говорит сервис CANIUSE о доступности определенной функции, которую необходимо использовать. Вы можете использовать все, что вам нравится, а полифилы помогут заполнить пробелы. Было время, когда, если вы хотели использовать необычную новую функцию браузера, вам нужно было найти полифил, а затем подключить его на свою страницу. Делать это для всех функций, отсутствующих в IE9, было бы трудной задачей. Теперь же все гораздо проще. Достаточно добавить одну строку:


<script src="https://cdn.polyfill.io/v2/polyfill.min.js"></script>

Этот простой скрипт может заполнить все что угодно. Если вы не слышали об этом сервисе полифила от Financial Times, вы можете прочитать об этом на polyfill.io.

Итерация NodeList в 2017

Популярность библиотеки jQuery было обусловлена не только исключительно ее способностью надежно устранять ошибки браузера и несоответствия в старом IE. На сегодняшний день у jQuery есть еще одно серьезное преимущество - итерация.

Вполне разумно, что списки NodeList нельзя перебирать (итерировать). Разработчикам до сих пор приходится прыгать через обручи, чтобы сделать их такими. Классический цикл for может быть наиболее оптимизированным по производительности подходом, но не всякому понравится набирать кучу текста. И вот мы уже приходим к такому безобразию:


var myArrayFromNodeList = [].slice.call(document.querySelectorAll('li'));

Или


[].forEach.call(myNodeList, function (item) {...}

Совсем недавно появился Array.from, предоставивший более изящный способ превратить nodeList в массив.


Array.from(querySelectorAll('li')).forEach((li) => /* что-то делаем с li */);

Но вот пришла грандиозная новость - списки NodeList теперь могут перебираться по умолчанию!

Теперь достаточно написать:


document.querySelectorAll('li').forEach((li) => /* что-то делаем */);

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

jQuery медленная?

Библиотека jQuery может быть гораздо быстрее коряво написанного чистого JS. Но это только лишний повод лучше изучить JavaScript! Один из создателей jQuery Пол Айриш в свое время писал в Twitter, что лучше на работающем сайте отказаться от использования методов show()/hide() в пользу классов, так как они снижают скорость работы сайта.

Вот что написал создатель jQuery о изучении нативного DOM в своей книге по Javascript "Secrets of the JavaScript Ninja":

"Зачем вам нужно понимать, как это работает, если библиотека позаботится об этом за вас? Наиболее убедительной причиной является производительность. Понимание того, как модификация DOM работает в библиотеках, позволяет вам писать более качественный и быстрый код."

Что мне не нравится в jQuery

Вместо того, чтобы сглаживать только остающиеся уродливые части некоторых браузерных API, jQuery стремится заменить их все оптом. Возвращая объект jQuery, а не NodeList, библиотека по сути закрывает встроенные методы браузера, что означает, что вы вынуждены абсолютно все делать через jQuery. Для новичков то, что когда-то было доступно посредством интерфейсных скриптов, теперь является препятствием, поскольку по сути это означает, что есть два дублирующих способа все сделать. Если вы хотите легко читать чужой код и применять его как к заданиям, требующим чистого JS, так и к заданиям, требующим jQuery, вам придется учиться вдвое больше. Однако есть библиотеки, которые приняли API, который будет достаточно знаком поклонникам jQuery, но который возвращает NodeList, а не объект jQuery.

Не можете жить без $?

Возможно, вы полюбили этот $ от jQuery. К счастью, есть ряд микробиблиотек, которые эмулируют API jQuery.

  • Леа Веру, приглашенный эксперт из рабочей группы W3C CSS, написавшая статью о вреде jQuery, является автором Bliss.js. Bliss использует знакомый синтаксис $, но возвращает NodeList.
  • Тем временем, Пол Ирриш выпустил Bling.js "потому что вы хотите получить $ jQuery без jQuery".
  • А Реми Шарп предложил аналогичную микробиблиотеку, метко названную min.js.

Тем не менее, не стоит думать, что мы ярые противники jQuery. Некоторые великие разработчики все еще предпочитают использовать именно эту библиотеку. Если вы комфортно чувствуете себя, используя jQuery, и вы знаете его API как свои пять пальцев, то нет никакой значительной причины выкидывать его в мусорное ведро. В конце концов, есть люди, которые используют jQuery и знают, что такое замыкание, и которые пишут веб-приложения корпоративного уровня, и есть люди, которые используют чистый JS, но не лезут в разработку сверх-приложений. При этом, множество вакансий программистов числят его среди необходимых навыков. Хотя для любого, кто только начинает свой путь на этом поприще, jQuery все чаще выглядит плохим выбором. Internet Explorer 11, к счастью, является окончательной версией этого адского устройства. Как только IE умрет, весь ландшафт браузеров станет вечно зеленым, а jQuery будет все больше и больше восприниматься как пережиток грязного прошлого DOM.