jQuery против document.querySelectorAll

161

Несколько раз я слышал, что самым сильным активом jQuery является то, как он запрашивает и манипулирует элементами в DOM: вы можете использовать CSS-запросы для создания сложных запросов, которые было бы очень сложно выполнить в обычном javascript. Однако, насколько мне известно, вы можете достичь того же результата с помощью document.querySelectorили document.querySelectorAll, которые поддерживаются в Internet Explorer 8 и выше.

Таким образом, вопрос заключается в следующем: зачем «рисковать» издержками jQuery, если его самый сильный актив может быть достигнут с помощью чистого JavaScript?

Я знаю, что jQuery имеет больше, чем просто CSS-селекторы, например, кросс-браузерный AJAX, хорошее прикрепление событий и т. Д. Но его часть запросов - очень большая часть силы jQuery!

Есть предположения?

Joel_Blum
источник
4
(1) Обход / модификация DOM намного быстрее и проще с jQuery. (2) Он добавляет свои собственные селекторы, которые не будут работать в querySelectorметодах. (3) Делать вызовы AJAX намного быстрее и проще с jQuery. (4) Поддержка в IE6 +. Я уверен, что есть еще много моментов, которые можно сделать тоже.
Джеймс Аллардис
12
(5) ... сокращенная запись $ () для ленивых машинисток обязательна.
Декстер Хуинда
4
проще да почему быстрее? Насколько я знаю, jQuery переводит на обычный javascript ...
Joel_Blum
4
@ JamesAllardice - «весь этот беспорядок» для кросс-браузерного XMLHttpRequest - это, возможно, 30 строк кода, которые вы пишете один раз и помещаете в свою собственную библиотеку.
RobG
6
@RobG - Да, я не говорю, просто используйте jQuery, если это все, для чего вы пытаетесь его использовать. Это только одно из преимуществ. Если вам нужен легкий обход DOM, AJAX и все querySelectorAll, что вам нужно для работы в старых браузерах, тогда jQuery - очевидный выбор. Я не говорю, что вы должны использовать это так .
Джеймс Аллардис

Ответы:

127

document.querySelectorAll() имеет несколько несоответствий в разных браузерах и не поддерживается в старых браузерах. Это, вероятно, больше не вызовет проблем в наши дни . У него очень не интуитивно понятный механизм обзора и некоторые другие не очень приятные функции . Также с javascript вам сложнее работать с результирующими наборами этих запросов, что во многих случаях может потребоваться. JQuery предоставляет функции для работы на них , как: filter(), find(), children(), parent(), map(), not()и еще несколько. Не говоря уже о способности jQuery работать с селекторами псевдоклассов.

Тем не менее, я бы не считал эти вещи сильнейшими функциями jQuery, а другими вещами, такими как «работа» над dom (события, стили, анимация и манипуляции) совместимым с кросс-браузером способом или интерфейсом ajax.

Если вам нужен только механизм выбора из jQuery, вы можете использовать тот, который использует сам jQuery: Sizzle. Таким образом, вы получаете мощь механизма выбора jQuerys без неприятных накладных расходов.

РЕДАКТИРОВАТЬ: Просто для записи, я большой фанат JavaScript JavaScript. Тем не менее, это факт, что вам иногда нужно 10 строк JavaScript, где вы бы написали 1 строку jQuery.

Конечно, вы должны быть дисциплинированными, чтобы не писать jQuery следующим образом:

$('ul.first').find('.foo').css('background-color', 'red').end().find('.bar').css('background-color', 'green').end();

Это чрезвычайно трудно прочитать, хотя последнее довольно ясно:

$('ul.first')
   .find('.foo')
      .css('background-color', 'red')
.end()
   .find('.bar')
      .css('background-color', 'green')
.end();

Эквивалентный JavaScript будет гораздо более сложным, что иллюстрируется приведенным выше псевдокодом:

1) Найдите элемент, рассмотрите возможность взять весь элемент или только первый.

// $('ul.first')
// taking querySelectorAll has to be considered
var e = document.querySelector("ul.first");

2) Выполните итерацию по массиву дочерних узлов с помощью некоторых (возможно, вложенных или рекурсивных) циклов и проверьте класс (список классов доступен не во всех браузерах!)

//.find('.foo')
for (var i = 0;i<e.length;i++){
     // older browser don't have element.classList -> even more complex
     e[i].children.classList.contains('foo');
     // do some more magic stuff here
}

3) применить стиль CSS

// .css('background-color', 'green')
// note different notation
element.style.backgroundColor = "green" // or
element.style["background-color"] = "green"

Этот код будет как минимум в два раза больше строк кода, которые вы пишете с помощью jQuery. Кроме того, вам придется учитывать кросс-браузерные проблемы, которые компрометируют серьезное преимущество в скорости (помимо надежности) нативного кода.

Christoph
источник
33
Какого рода несоответствия querySelectorAllмежду браузерами? И как с помощью jQuery решить эту проблему, поскольку jQuery использует, querySelectorAll когда доступно?
3
Правда, одна строка кода может содержать цепочки бесконечных кодов, которые могут сильно раздражать при отладке.
Декстер Хуинда
1
«2) перебрать массив дочерних узлов с помощью некоторых (возможно, вложенных или рекурсивных) циклов и проверить класс« << Это полная чушь. Вы можете использовать querySelectorAll для элемента на предыдущем шаге.
Вануан
5
@ Vanan, в этом может не быть необходимости, но, если бы вы внимательно прочитали мой ответ, вы бы заметили, что у querySelector есть серьезная проблема с областями видимости, которая может дать вам много ложных срабатываний при использовании так, как вы предлагаете. Тем не менее, хотя вы свободны повышать или понижать голос по какой-то придирчивой причине, я думаю, что это не повод использовать грубый язык.
Кристоф
2
@Christoph Так как это легко, я добавил совместимость для IE8 и выше. По-прежнему огромные скоростные преимущества (в 5-20 раз). То, что код будет работать медленнее в старом браузере, таком как IE8, является неверным предположением.
Паскалий
60

Если вы оптимизируете свою страницу для IE8 или новее, вам следует подумать, нужен ли вам jquery или нет. Современные браузеры изначально имеют множество ресурсов, которые предоставляет jquery.

Если вы заботитесь о производительности, вы можете получить невероятные преимущества в производительности (на 2-10 раз быстрее), используя собственный javascript: http://jsperf.com/jquery-vs-native-selector-and-element-style/2

Я преобразовал div-tagcloud из jquery в нативный javascript (совместимый с IE8 +), результаты впечатляют. В 4 раза быстрее, с небольшими накладными расходами.

                    Number of lines       Execution Time                       
Jquery version :        340                    155ms
Native version :        370                    27ms

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

http://youmightnotneedjquery.com/


Приложение: дальнейшее сравнение скорости, как нативные методы конкурируют с jquery

Pascalius
источник
хороший обзор, хотя некоторые примеры кода ошибочны ... Например, $(el).find(selector)это не равно, el.querySelectorAll(selector)а производительность нативных методов часто ужасна: stackoverflow.com/q/14647470/1047823
Кристоф
@Christoph Можете ли вы уточнить, почему вы думаете, что методы разные? Конечно, есть крайние случаи, когда jquery может работать лучше, но я не видел ни одного для DOM-Manipulation.
Паскалий
1
Не нужно углубляться в подробности, просто прочитайте мой ответ, посмотрите на скрипку и статью, на которую я ссылался. Кроме того, (по крайней мере, atm) большинство нативных методов Array уступают по скорости по сравнению с наивной реализацией js (как я упоминал в вопросе в моем первом комментарии). И это не крайние случаи, а скорее стандартный случай. Но, опять же, основным вопросом в этом вопросе была не скорость.
Кристоф
2
@Christoph Конечно, эти методы не на 100% равны, и JQuery часто обеспечивает больше удобства. Я обновил ответ, чтобы показать, что это всего лишь крайний случай, и на самом деле я не смог найти ни одного другого случая, когда jquery работал лучше. Там нет основной направленности вопроса.
Паскалий
+1 Отличный ответ! В течение последних 4 или 5 лет я постепенно заменял старый код jQuery на сырой JavaScript везде и всегда, когда это было возможно. Конечно, jQuery отлично подходит для некоторых вещей, и я использую его для тех вещей, когда чувствую, что получаю солидную выгоду.
Да Барри
13

Чтобы понять, почему jQuery так популярен, важно понять, откуда мы пришли!

Около десяти лет назад лучшими браузерами были IE6, Netscape 8 и Firefox 1.5. В те времена было мало кросс-браузерных способов выбора элемента из DOM Document.getElementById().

Итак, когда jQuery был выпущен в 2006 году , это было довольно революционно. Тогда jQuery установил стандарт того, как легко выбирать / изменять элементы HTML и инициировать события, потому что его гибкость и поддержка браузера были беспрецедентными.

Теперь, более десяти лет спустя, многие функции, которые сделали jQuery столь популярным, стали включены в стандарт javaScript:

Они вообще не были доступны еще в 2005 году. Тот факт, что они существуют сегодня, очевидно, ставит вопрос о том, почему мы вообще должны использовать jQuery. И действительно, люди все чаще задаются вопросом, стоит ли вообще использовать jQuery .

Так что, если вы думаете, что понимаете JavaScript достаточно хорошо, чтобы обходиться без jQuery, пожалуйста! Не пытайтесь использовать jQuery только потому, что так делают многие другие!

Джон Слегерс
источник
7

Это потому, что JQuery может сделать гораздо больше, чем querySelectorAll.

Прежде всего, jQuery (и Sizzle, в частности) работает для старых браузеров, таких как IE7-8, которые не поддерживают селекторы CSS2.1-3.

Кроме того, Sizzle (который является движком селектора позади jQuery) предлагает вам множество более продвинутых инструментов селектора, таких как :selectedпсевдокласс, расширенный :not()селектор, более сложный синтаксис, такой как in $("> .children")и так далее.

И он делает это кросс-браузеров, безупречно, предлагая все, что может предложить jQuery (плагины и API).

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

MaxArt
источник
7

Селекторный движок jQuery Sizzle может использовать, querySelectorAllесли он доступен. Это также сглаживает несоответствия между браузерами для достижения единообразных результатов. Если вы не хотите использовать все jQuery, вы можете просто использовать Sizzle отдельно. Это довольно фундаментальное колесо для изобретения.

Вот некоторые черри из источника, которые показывают, что jQuery (w / Sizzle) выбирает для вас:

Режим причуда Safari:

if ( document.querySelectorAll ) {
  (function(){
    var oldSizzle = Sizzle,
      div = document.createElement("div"),
      id = "__sizzle__";

    div.innerHTML = "<p class='TEST'></p>";

    // Safari can't handle uppercase or unicode characters when
    // in quirks mode.
    if ( div.querySelectorAll && div.querySelectorAll(".TEST").length === 0 ) {
      return;
    }

Если этот охранник не работает, он использует версию Sizzle, которая не улучшена querySelectorAll. Кроме того, есть специальные маркеры несоответствий в IE, Opera и браузере Blackberry.

  // Check parentNode to catch when Blackberry 4.6 returns
  // nodes that are no longer in the document #6963
  if ( elem && elem.parentNode ) {
    // Handle the case where IE and Opera return items
    // by name instead of ID
    if ( elem.id === match[3] ) {
      return makeArray( [ elem ], extra );
    }

  } else {
    return makeArray( [], extra );
  }

И если все остальное терпит неудачу, это возвратит результат oldSizzle(query, context, extra, seed).

KGZM
источник
6

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

Одним из основных является то, что они хорошо документированы и имеют сообщества, такие как ... скажем ... stackexchange, где можно найти помощь по библиотекам. С пользовательской кодированной библиотекой у вас есть исходный код и, возможно, документ с практическими рекомендациями, если только кодеры не потратили больше времени на документирование кода, чем на его написание, что крайне редко встречается.

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

Назовите это сетевым эффектом, если хотите. Это не значит, что код будет лучше в jQuery; только то, что лаконичный характер кода облегчает понимание общей структуры для программистов всех уровней квалификации, хотя бы потому, что в просматриваемом файле сразу виден более функциональный код. В этом смысле 5 строк кода лучше, чем 10.

Подводя итог, я вижу основные преимущества jQuery как лаконичность кода и повсеместность.

Дом Дей
источник
6

Вот сравнение, если я хочу применить тот же атрибут, например, скрыть все элементы класса "my-class". Это одна из причин использовать jQuery.

JQuery:

$('.my-class').hide();

JavaScript:

var cls = document.querySelectorAll('.my-class');
for (var i = 0; i < cls.length; i++) {
    cls[i].style.display = 'none';
}

Поскольку jQuery уже настолько популярен, они должны были заставить document.querySelector () вести себя так же, как $ (). Вместо этого document.querySelector () выбирает только первый соответствующий элемент, что делает его полезным только наполовину.

Стивен
источник
4
Я хотел бы сделать. Для каждого здесь.
Филипп Сенн
Ну, вы всегда можете пойти по более легкому маршруту document.querySelectorAll('.my-class').forEach(el => el.style.display = 'none');. Тем не менее, даже если короче, производительность родной всегда лучше.
Ален Круз
С точки зрения пользователя, все, что происходит менее чем за 0,1 сек, происходит немедленно. Поэтому native даже быстрее, лучше только в том случае, если реализация jQuery медленнее, чем 0,1 сек. И в реальном мире это не так.
Юрин
3

как говорится на официальном сайте: «jQuery: пиши меньше, делай больше, библиотека JavaScript»

попробуйте перевести следующий код JQuery без какой-либо библиотеки

$("p.neat").addClass("ohmy").show("slow");
Саймон Сюй
источник
1
Я согласен с этим, однако как насчет читабельности? Как вы можете документировать длинные строки кода с множеством несвязанных вещей? Как вы можете отлаживать такие чудовища?
Joel_Blum
@ user1032663 это вопрос документации-соглашений.
Кристоф
1
Альтернатива jQuery (или любой другой «популярной» библиотеке, которую вы выбираете) - это не писать все с нуля, а использовать библиотеку, которая соответствует вашим целям и хорошо написана. Вы, возможно, написали части самостоятельно или выбрали модульную библиотеку, такую ​​как MyLibrary чтобы включить в нее только то, что вам нужно.
RobG
2
Пример, который вы выбрали, на самом деле не подтверждает вашу точку зрения: вопрос заключается в поиске различий в провинции «селектор». addClass()и на show()самом деле не считается. А что касается $('p.neat'), вы можете взглянуть на querySelector / All.
kumarharsh
document.querySelectorAll('p.neat').forEach(p=>p.classList.add('ohmy'));и пусть CSS сделает все остальное Чуть более длинный код, но гораздо эффективнее. Конечно, его решение было не так доступно в Legacy IE дней. Часть «Делай больше» иронична. JQuery требует около ста строк кода, чтобы найти что-то, поэтому делать больше не всегда продуктивно.
Манго
2

Я думаю, что правильный ответ заключается в том, что jQuery был разработан задолго до того, как querySelector/querySelectorAllстал доступен во всех основных браузерах.

Первоначальный выпуск jQuery был в 2006 году . На самом деле, даже jQuery не был первым, кто реализовал CSS-селекторы .

IE был последним браузером для реализации querySelector/querySelectorAll. Его восьмая версия была выпущена в 2009 году .

Так что теперь селекторы DOM-элементов больше не являются сильной стороной jQuery. Тем не менее, у него все еще есть много положительных моментов, таких как ярлыки для изменения содержимого CSS и html элемента, анимации, привязка событий, ajax.

Vanuan
источник
1

Старый вопрос, но спустя пол десятилетия стоит вернуться. Здесь я обсуждаю только селекторный аспект jQuery.

document.querySelector[All]поддерживается всеми текущими браузерами, вплоть до IE8, поэтому совместимость больше не является проблемой. Я также не нашел проблем с производительностью, чтобы говорить о (это должно было быть медленнее, чемdocument.getElementById , но мое собственное тестирование показывает, что это немного быстрее).

Поэтому, когда дело доходит до манипулирования элементом напрямую, оно должно быть предпочтительнее, чем jQuery.

Например:

var element=document.querySelector('h1');
element.innerHTML='Hello';

это значительно выше:

var $element=$('h1');
$element.html('hello');

Чтобы что-то сделать вообще, jQuery должен пройти через сто строк кода (я однажды проследил код, такой как приведенный выше, чтобы увидеть, что на самом деле делал с ним jQuery). Это явно пустая трата времени каждого.

Другая значительная стоимость jQuery заключается в том, что он оборачивает все внутри нового объекта jQuery. Эти издержки особенно расточительны, если вам нужно снова развернуть объект или использовать один из методов объекта для работы со свойствами, которые уже представлены в исходном элементе.

Однако преимущество jQuery заключается в том, как он обрабатывает коллекции. Если требуется установить свойства нескольких элементов, jQuery имеет встроенный eachметод, который позволяет что-то вроде этого:

var $elements=$('h2');  //  multiple elements
$elements.html('hello');

Для этого с Vanilla JavaScript потребуется что-то вроде этого:

var elements=document.querySelectorAll('h2');
elements.forEach(function(e) {
    e.innerHTML='Hello';
});

что некоторые находят пугающим.

Селекторы jQuery также немного отличаются, но современные браузеры (исключая IE8) не принесут особой пользы.

Как правило, я предостерегаю от использования jQuery для новых проектов:

  • jQuery - это внешняя библиотека, которая увеличивает накладные расходы проекта и вашу зависимость от третьих сторон.
  • Функция jQuery очень дорогая, с точки зрения обработки.
  • JQuery навязывает методологию, которая должна быть изучена и может конкурировать с другими аспектами вашего кода.
  • jQuery не спешит раскрывать новые функции в JavaScript.

Если ничего из вышеперечисленного не имеет значения, делайте что хотите. Однако jQuery уже не так важен для кроссплатформенной разработки, как раньше, поскольку современные JavaScript и CSS идут намного дальше, чем раньше.

Это не упоминает о других функциях jQuery. Однако я думаю, что им тоже нужно присмотреться.

Manngo
источник
1
Ваш синтаксис даже не верен, не говоря уже о других неправильных вещах, таких как «медленное раскрытие новых функций в Javascript» Работа JQuery даже не раскрывает новые функции, а облегчает вам манипулирование DOM и выполнение простых вещей, которые могут быть как 10 строк в Javascript. Весь ваш комментарий просто не имеет никакого смысла и содержит много неправильных вещей. Подумайте об улучшении этого.
Мальчик про
@Boypro Спасибо за ваш комментарий, но он тоже полон ошибок. Возможно, вы хотели бы поделиться тем, что именно о моем ответе так сильно вас оскорбляет. Что «даже не правильно». Еще лучше, вы могли бы внести свой собственный ответ. Вопрос о стоимости использования jQuery, когда ванильный JavaScript может сделать так много. Подумайте над ответом.
Manngo
0
$ ("# id") против document.querySelectorAll ("# id")

Дело в том, что с функцией $ () она создает массив, а затем разбивает его на вас, но с document.querySelectorAll () она создает массив, и вам нужно разбить его.


источник
0

Просто комментарий по этому поводу: при использовании lite design design, jquery selector по какой-то причине не возвращает свойство для design design.

Для:

<div class="logonfield mdl-textfield mdl-js-textfield mdl-textfield--floating-label">
        <input class="mdl-textfield__input" type="text" id="myinputfield" required>
        <label class="mdl-textfield__label" for="myinputfield">Enter something..</label>
      </div>

Это работает:

document.querySelector('#myinputfield').parentNode.MaterialTextfield.change();

Это не:

$('#myinputfield').parentNode.MaterialTextfield.change();
Эшвин Бхутту
источник