jQuery vs document.querySelectorAll


161

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

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

Я знаю, що jQuery має більше, ніж просто CSS-селектори, наприклад крос-браузер AJAX, приємне приєднання подій тощо. Але його частина запиту - це дуже велика частина сили jQuery!

Будь-які думки?


4
(1) Обхід / модифікація DOM набагато швидше та простіше за допомогою jQuery. (2) Він додає власні селектори, які не працюватимуть у querySelectorметодах. (3) Здійснювати дзвінки AJAX набагато швидше та простіше за допомогою jQuery. (4) Підтримка в IE6 +. Я впевнений, що є багато інших пунктів, які також можна зробити.
Джеймс Еллардіс

12
(5) ... скорочення $ () для ледачих машиністів - обов'язкове.
Dexter Huinda

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, але інші речі, такі як "робота" на домі (події, стилізація, анімація та маніпуляції) в сумісному режимі з перехресним браузером або в інтерфейсі ajax.

Якщо ви хочете лише двигун селектора від jQuery, ви можете використовувати той самий jQuery: Sizzle Таким чином, ви маєте силу двигуна jQuerys Selector без неприємних накладних витрат.

EDIT: Тільки для запису, я величезний шанувальник JavaScript ванілі. Тим не менш, факт, що вам іноді потрібно 10 рядків JavaScript, де ви писали б jQuery з 1 рядком.

Звичайно, ви повинні бути дисциплінованими, щоб не писати 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. Крім того, вам доведеться враховувати проблеми, пов’язані з браузером, які будуть загрожувати серйозній перевазі швидкості (крім надійності) нативного коду.


33
Які невідповідності querySelectorAllміж браузерами? І як би за допомогою jQuery вирішити це, оскільки jQuery використовує, querySelectorAll коли він доступний?

3
Правда, один рядок коду може містити ланцюжки нескінченних кодів, які можуть дуже дратувати під час налагодження.
Dexter Huinda

1
"2) повторіть масив дочірніх кодів через деякі (можливо, вкладені або рекурсивні) петлі та перевірте клас" << Це загальне сканування. Ви можете використовувати querySelectorAll для елемента на попередньому кроці.
Вануан

5
@ Вануан це може не знадобитися, але якби ви уважно прочитали мою відповідь, ви помітили б, що 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


приємний огляд, хоча деякі приклади коду помиляються ... Наприклад, $(el).find(selector)це не дорівнює, el.querySelectorAll(selector)а ефективність власних методів часто буває жахливою: stackoverflow.com/q/14647470/1047823
Крістоф

@Christoph Чи можете ви детальніше пояснити, чому ви вважаєте, що методи відрізняються? Звичайно, є крайні випадки, коли jquery може працювати краще, але я не бачив жодного для DOM-маніпуляції.
Паскалій

1
Не потрібно більше деталізуватись, просто прочитайте мою відповідь, подивіться на загадку та статтю, до якої я пов’язаний. Крім того, (принаймні атм) більшість нативних методів Array поступаються за швидкістю порівняно з наївним реалізацією js (як я пов’язаний у питанні у своєму першому коментарі). І це не крайові випадки, а скоріше стандартний випадок. Але знову ж таки, головна увага в цьому питанні була не швидкість.
Крістоф

2
@Christoph Звичайно, ці методи не на 100% рівні, і jquery часто забезпечує більше зручності. Я оновив відповідь, щоб показати, що це лише крайній випадок, я фактично не міг знайти жодного іншого випадку, коли jquery працював краще. Основної уваги питання немає.
Паскалій

+1 Відмінна відповідь! Я повільно замінював старий код jQuery на сирий JavaScript протягом останніх 4 або 5 років, де і коли це можливо. Звичайно, jQuery чудово підходить для деяких речей, і я використовую його для тих речей, коли відчуваю, що отримую міцну користь.
Так, Баррі

13

Щоб зрозуміти, чому jQuery настільки популярний, важливо зрозуміти, звідки ми родом!

Близько десятиліття тому топ-браузерами були IE6, Netscape 8 та Firefox 1.5. Ще в ті часи було мало крос-браузерних способів вибору елемента з DOMDocument.getElementById() .

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

Тепер, більш ніж через десятиліття, у стандарт javaScript включено безліч функцій, які зробили jQuery таким популярним:

Вони взагалі не були доступні ще в 2005 році. Те, що вони є сьогодні, очевидно, ставить питання, чому ми взагалі повинні використовувати jQuery. І справді, люди все частіше задаються питанням, чи варто взагалі використовувати jQuery .

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


7

Це тому, що jQuery може зробити набагато більше, ніж querySelectorAll.

Перш за все, jQuery (і Sizzle, зокрема), працює для старих браузерів, таких як IE7-8, який не підтримує CSS2.1-3 селектори.

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

І це робить це крос-браузери, бездоганно, пропонуючи все, що може запропонувати jQuery (плагіни та API).

Так, якщо ви думаєте, що можете покластися на прості селектори та ідентифікатори, jQuery - це занадто багато для вас, і ви б платили завищену оплату. Але якщо ви цього не зробите і хочете скористатися всіма благами jQuery, тоді використовуйте це.


7

Двигун Sizzle із функцією jQuery може використовувати, 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).


6

Що стосується ремонтоздатності коду, існує декілька причин дотримуватися широко використовуваної бібліотеки.

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

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

Назвіть це мережевий ефект, якщо хочете. Це не означає, що код буде вище в jQuery; лише те, що стислий характер коду полегшує зрозуміти загальну структуру для програмістів усіх рівнів кваліфікації, хоча б тому, що у переглянутому файлі одразу видно більш функціональний код. У цьому сенсі 5 рядків коду краще, ніж 10.

Підводячи підсумок, я бачу основні переваги jQuery як стислий код та повсюдність.


6

Ось порівняння, якщо я хочу застосувати той самий атрибут, наприклад приховати всі елементи класу "мій клас". Це одна з причин використовувати 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 сек, відбувається негайно. Тому рідне, навіть будучи швидше, краще лише у випадку, коли реалізація 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.
кумархарш

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.


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');

Для цього з ванільним 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. Однак я думаю, що вони теж потребують уважнішого огляду.


1
У вашому синтаксисі навіть неправильно не згадувати інші помилкові речі, такі як "повільно виставляти нові функції у Javascript" Завдання JQuery навіть не відкривати нові функції, це полегшити вам DOM маніпулювати та робити прості речі, які можуть бути як 10 рядків у Javascript. Увесь ваш коментар просто не має ніякого сенсу і в ньому є багато неправильних речей. Подумайте про її вдосконалення.
Хлопчик про

@Boypro Дякую за ваш коментар, але він теж повний помилок. Можливо, ви хотіли б поділитися тим, що саме про мою відповідь так сильно ображає вас. Що "навіть не правильно". А ще краще, можливо, ви хочете внести свій власний привід. Питання полягає у вартості використання jQuery, коли ванільний JavaScript може зробити стільки. Розглянемо відповідь на це.
Манго

0
$ ("# id") vs document.querySelectorAll ("# id")

Угода полягає в функції $ (), вона створює масив, а потім розбиває його для вас, але за допомогою document.querySelectorAll () він створює масив, і вам доведеться розбити його.


0

Лише зауваження до цього, коли використовується дизайн дизайну Lite, селектор jquery чомусь не повертає властивість для дизайну матеріалів.

Для:

<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();
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.