jQuery vs document.querySelectorAll


161

Ho sentito diverse volte che la risorsa più forte di jQuery è il modo in cui interroga e manipola elementi nel DOM: è possibile utilizzare query CSS per creare query complesse che sarebbe molto difficile eseguire in javascript normale. Tuttavia, per quanto ne so, puoi ottenere lo stesso risultato con document.querySelectoro document.querySelectorAll, che sono supportati in Internet Explorer 8 e versioni successive.

Quindi la domanda è questa: perché 'sovraccaricare' l'overhead di jQuery se la sua risorsa più forte può essere raggiunta con JavaScript puro?

So che jQuery ha più di un semplice selettore CSS, ad esempio cross-browser AJAX, un bel collegamento di eventi ecc. Ma la sua parte di interrogazione è una parte molto grande della forza di jQuery!

qualche idea?


4
(1) L'attraversamento / modifica del DOM è molto più rapido e semplice con jQuery. (2) Aggiunge i propri selettori che non funzioneranno nei querySelectormetodi. (3) Effettuare chiamate AJAX è molto più semplice e veloce con jQuery. (4) Supporto in IE6 +. Sono sicuro che ci sono anche molti altri punti che potrebbero essere sollevati.
James Allardice,

12
(5) ... la scorciatoia $ () per i dattilografi pigri è un must.
Dexter Huinda,

4
più facile sì, perché più veloce? jQuery si traduce in javascript normale per quanto ne so ...
Joel_Blum,

4
@ JamesAllardice: "tutto quel casino" per XMLHttpRequest tra browser è forse 30 righe di codice che scrivi una volta e che metti nella tua libreria.
RobG

6
@RobG - Sì, non sto dicendo solo di usare jQuery se è tutto ciò per cui stai cercando di usarlo. È solo uno dei vantaggi. Se hai bisogno di un facile DOM traversal, AJAX e querySelectorAll, e hai bisogno di tutto per funzionare nei browser più vecchi, allora jQuery è una scelta ovvia. Non sto dicendo che dovresti usarlo in questo modo .
James Allardice,

Risposte:


127

document.querySelectorAll() ha diverse incongruenze tra i browser e non è supportato nei browser più vecchi Questo probabilmente non causerà più problemi al giorno d'oggi . Ha un meccanismo di scoping molto poco intuitivo e alcune altre caratteristiche non così belle . Inoltre con JavaScript hai più difficoltà a lavorare con i set di risultati di queste query, che in molti casi potresti voler fare. jQuery fornisce funzioni per il lavoro su di loro come: filter(), find(), children(), parent(), map(), not()e molti altri. Per non parlare della capacità di jQuery di lavorare con selettori di pseudo-classe.

Tuttavia, non considererei queste cose come le caratteristiche più forti di jQuery ma altre cose come "lavorare" sul dom (eventi, stile, animazione e manipolazione) in modo compatibile con i browser o l'interfaccia ajax.

Se vuoi solo il motore di selezione da jQuery puoi usare quello che jQuery stesso sta usando: Sizzle In questo modo hai la potenza del motore di selezione di jQuerys senza il fastidioso sovraccarico.

EDIT: Solo per la cronaca, sono un grande fan di JavaScript vaniglia. Tuttavia è un dato di fatto che a volte sono necessarie 10 righe di JavaScript in cui scrivere jQuery 1 riga.

Ovviamente devi essere disciplinato per non scrivere jQuery in questo modo:

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

Questo è estremamente difficile da leggere, mentre quest'ultimo è piuttosto chiaro:

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

Il JavaScript equivalente sarebbe molto più complesso illustrato dallo pseudocodice sopra:

1) Trova l'elemento, considera di prendere tutto l'elemento o solo il primo.

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

2) Scorrere la matrice di nodi figlio tramite alcuni loop (possibilmente nidificati o ricorsivi) e controllare la classe (elenco di classi non disponibile in tutti i browser!)

//.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) applica lo stile css

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

Questo codice sarebbe almeno due volte più righe di codice che scrivi con jQuery. Inoltre, dovresti considerare i problemi tra browser che comprometteranno il grave vantaggio di velocità (oltre all'affidabilità) del codice nativo.


33
Che tipo di incoerenze querySelectorAllha tra i browser? E come potrebbe risolvere questo problema usando jQuery, poiché jQuery lo utilizza querySelectorAll quando disponibile?

3
È vero, una riga di codice può contenere catene di codici infiniti che possono essere molto fastidiosi durante il debug.
Dexter Huinda,

1
"2) iterare sull'array di nodi secondari tramite alcuni loop (possibilmente annidati o ricorsivi) e controllare la classe" << Questa è una merda totale. È possibile utilizzare querySelectorAll sull'elemento nel passaggio precedente.
Vanuan,

5
@Vanuan questo potrebbe non essere necessario, ma se avessi letto attentamente la mia risposta avresti notato che querySelector ha un grave problema di scoping che potrebbe darti molti falsi positivi se usato nel modo in cui lo proponi. Tuttavia, mentre sei libero di aumentare o diminuire il voto per qualche motivo nitido, penso che non sia un motivo per usare un linguaggio volgare.
Christoph,

2
@Christoph Poiché questo è facile, ho aggiunto la compatibilità per IE8 e versioni successive. Ancora enormi vantaggi di velocità (5-20 volte). Che il codice funzionerà più lentamente nel vecchio browser come IE8 è solo un presupposto sbagliato.
Pascalio,

60

Se stai ottimizzando la tua pagina per IE8 o più recente, dovresti davvero considerare se hai bisogno di jquery o meno. I browser moderni hanno molte risorse nativamente fornite da jquery.

Se ti interessano le prestazioni, puoi ottenere incredibili vantaggi in termini di prestazioni (2-10 più veloce) utilizzando JavaScript nativo: http://jsperf.com/jquery-vs-native-selector-and-element-style/2

Ho trasformato un div-tagcloud da jquery a javascript nativo (compatibile con IE8 +), i risultati sono impressionanti. 4 volte più veloce con solo un po 'di sovraccarico.

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

Potrebbe non essere necessario Jquery offre una panoramica davvero piacevole, che i metodi nativi sostituiscono per quale versione del browser.

http://youmightnotneedjquery.com/


Appendice: ulteriori confronti di velocità su come i metodi nativi competono con jquery


bella panoramica anche se alcuni degli esempi di codice sono sbagliati ... Ad esempio, $(el).find(selector)non è uguale a el.querySelectorAll(selector)e le prestazioni dei metodi nativi sono spesso piuttosto orribili: stackoverflow.com/q/14647470/1047823
Christoph

@Christoph Puoi approfondire, perché pensi che i metodi siano diversi? Ovviamente ci sono casi limite in cui jquery può funzionare meglio, ma non ne ho visto uno per la manipolazione DOM.
Pascalius,

1
Non c'è bisogno di approfondire, basta leggere la mia risposta, guardare il violino e l'articolo a cui mi sono collegato. Inoltre, (almeno atm) la maggior parte dei metodi Array nativi ha una velocità inferiore rispetto a un'implementazione js ingenua (come ho collegato nella domanda nel mio primo commento). E questi non sono casi limite, ma piuttosto il caso standard. Ma ancora una volta, l'obiettivo principale di questa domanda non era la velocità.
Christoph,

2
@Christoph Naturalmente, questi metodi non sono uguali al 100% e spesso jquery offre maggiore praticità. Ho aggiornato la risposta per mostrare che questo è solo un caso limite, in realtà non sono riuscito a trovare nessun altro caso in cui jquery ha funzionato meglio. Non vi è alcun obiettivo principale della domanda.
Pascalius,

+1 Risposta eccellente! Negli ultimi 4 o 5 anni ho sostituito lentamente il vecchio codice jQuery con JavaScript non elaborato negli ultimi 4 o 5 anni, ovunque e quando possibile. Naturalmente, jQuery è ottimo per alcune cose e lo uso per quelle cose quando sento di ottenere un solido beneficio.
Sì, Barry,

13

Per capire perché jQuery è così popolare, è importante capire da dove veniamo!

Circa un decennio fa, i migliori browser erano IE6, Netscape 8 e Firefox 1.5. A quei tempi, c'erano anche pochi modi tra browser per selezionare un elemento dal DOM Document.getElementById().

Quindi, quando jQuery è stato rilasciato nel 2006 , è stato piuttosto rivoluzionario. All'epoca, jQuery stabiliva lo standard su come selezionare / modificare facilmente elementi HTML e attivare eventi, poiché la sua flessibilità e il supporto del browser non avevano precedenti.

Ora, più di un decennio dopo, molte funzioni che hanno reso così popolare jQuery sono state incluse nello standard javaScript:

Questi non erano generalmente disponibili nel 2005. Il fatto che siano oggi ovviamente pone la domanda sul perché dovremmo usare jQuery. E in effetti, le persone si chiedono sempre più se dovremmo usare jQuery .

Quindi, se pensi di capire JavaScript abbastanza bene da fare a meno di jQuery, per favore fallo! Non sentirti costretto a usare jQuery, solo perché molti altri lo stanno facendo!


7

Questo perché jQuery può fare molto di più querySelectorAll .

Innanzitutto, jQuery (e Sizzle, in particolare), funziona con browser meno recenti come IE7-8 che non supporta i selettori CSS2.1-3.

Inoltre, Sizzle (che è il motore di selezione dietro jQuery) offre molti strumenti di selezione più avanzati, come la :selectedpseudo-classe, un :not()selettore avanzato , una sintassi più complessa come in$("> .children") e così via.

E lo fa cross-browser, in modo impeccabile, offrendo tutto ciò che jQuery può offrire (plugin e API).

Sì, se pensi di poter fare affidamento su semplici selettori di classe e ID, jQuery è troppo per te e pagheresti un esagerato pay-off. Ma se non lo fai e vuoi approfittare di tutta la bontà di jQuery, allora usalo.


7

È possibile utilizzare il motore di selezione Sizzle di jQuery querySelectorAll se è disponibile. Risolve anche le incoerenze tra i browser per ottenere risultati uniformi. Se non vuoi usare tutto jQuery, puoi semplicemente usare Sizzle separatamente. Questa è una ruota piuttosto fondamentale da inventare.

Ecco alcune raccolte di ciliegie dalla fonte che mostrano il tipo di cose che jQuery (w / Sizzle) ordina per te:

Modalità stranezze 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;
    }

Se quella guardia fallisce, usa una versione di Sizzle che non è stata migliorata querySelectorAll. Più in basso ci sono maniglie specifiche per incoerenze in IE, Opera e nel browser 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 );
  }

E se tutto il resto fallisce, restituirà il risultato di oldSizzle(query, context, extra, seed).


6

In termini di manutenibilità del codice, ci sono diversi motivi per attenersi a una libreria ampiamente utilizzata.

Uno dei principali è che sono ben documentati e hanno comunità come ... diciamo ... stackexchange, dove è possibile trovare aiuto con le librerie. Con una libreria codificata personalizzata, hai il codice sorgente e forse un documento informativo, a meno che il / i programmatore / i non abbia trascorso più tempo a documentare il codice che a scriverlo, il che è assolutamente raro.

Scrivere la tua biblioteca potrebbe funzionare per te , ma il tirocinante seduto alla scrivania successiva potrebbe avere un tempo più facile alzarsi alla velocità con qualcosa come jQuery.

Chiamalo effetto di rete se vuoi. Questo non vuol dire che il codice sarà superiore in jQuery; solo che la natura concisa del codice semplifica la comprensione della struttura generale per i programmatori di tutti i livelli di abilità, anche solo perché nel file che si sta visualizzando è visibile contemporaneamente più codice funzionale. In questo senso, 5 righe di codice sono migliori di 10.

Per riassumere, vedo i principali vantaggi di jQuery come il codice conciso e l'ubiquità.


6

Ecco un confronto se voglio applicare lo stesso attributo, ad esempio nascondere tutti gli elementi della classe "my-class". Questo è uno dei motivi per usare 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';
}

Con jQuery già così popolare, avrebbero dovuto far sì che document.querySelector () si comportasse proprio come $ (). Al contrario, document.querySelector () seleziona solo il primo elemento corrispondente che lo rende utile solo a metà.


4
Vorrei fare un. Per ogni qui.
Phillip Senn,

Bene, puoi sempre seguire un percorso più semplice document.querySelectorAll('.my-class').forEach(el => el.style.display = 'none');. Tuttavia, anche se più breve, il nativo per quanto riguarda le prestazioni è sempre migliore.
Alain Cruz,

Dal punto di vista dell'utente, tutto ciò che accade in meno di 0,1 secondi, accade immediatamente. Quindi nativo è anche più veloce, meglio solo nel caso in cui l'implementazione di jQuery rallenti di 0,1 sec. E nell'applicazione del mondo reale non è mai il caso.
yurin

3

come dice il sito ufficiale: "jQuery: The Write Less, Do More, JavaScript Library"

prova a tradurre il seguente codice jQuery senza alcuna libreria

$("p.neat").addClass("ohmy").show("slow");

1
Sono d'accordo con ciò, tuttavia per quanto riguarda la leggibilità? come puoi documentare lunghe righe di codice con molte cose non correlate in corso? Come puoi eseguire il debug di tali mostruosità?
Joel_Blum,

@ user1032663 è una questione di convenzioni di documentazione.
Christoph,

1
L'alternativa a jQuery (o qualunque altra libreria "popolare" che scegli) non è scrivere tutto da zero, ma usare una libreria adatta al tuo scopo ed è ben scritta. È possibile che tu abbia scritto parti o scelto una libreria modulare come MyLibrary per includere solo ciò di cui hai bisogno.
RobG

2
L'esempio che hai scelto non dimostra davvero il tuo punto: la domanda è cercare differenze nella provincia del "selettore". addClass()e show()non conta davvero. E per quanto riguarda $('p.neat'), puoi dare un'occhiata a querySelector / All.
Kumarharsh,

document.querySelectorAll('p.neat').forEach(p=>p.classList.add('ohmy'));e lascia che CSS faccia il resto. Codice leggermente più lungo, ma molto più efficiente. Naturalmente, la sua soluzione non era così disponibile nei giorni di IE legacy. La parte "Fai di più" è ironica. jQuery impiega circa cento righe di codice per trovare qualcosa, quindi fare di più non è sempre produttivo.
Manngo,

2

Penso che la vera risposta sia che jQuery è stato sviluppato molto prima querySelector/querySelectorAll diventasse disponibile in tutti i principali browser.

La versione iniziale di jQuery è stata nel 2006 . In effetti, anche jQuery non è stato il primo a implementare i selettori CSS .

IE è stato l'ultimo browser a implementare querySelector/querySelectorAll. La sua ottava versione è stata rilasciata nel 2009 .

Quindi ora i selettori di elementi DOM non sono più il punto di forza di jQuery. Tuttavia, ha ancora un sacco di chicche nella manica, come scorciatoie per cambiare il contenuto css e html di elemento, animazioni, associazione di eventi, ajax.


1

Vecchia domanda, ma mezzo decennio dopo, vale la pena rivisitare. Qui sto solo discutendo l'aspetto selettore di jQuery.

document.querySelector[All]è supportato da tutti i browser attuali, fino a IE8, quindi la compatibilità non è più un problema. Inoltre non ho riscontrato problemi di prestazioni di cui parlare (avrebbe dovuto essere più lento di document.getElementById, ma i miei test suggeriscono che è leggermente più veloce).

Pertanto, quando si tratta di manipolare direttamente un elemento, è preferibile rispetto a jQuery.

Per esempio:

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

è notevolmente superiore a:

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

Per fare qualsiasi cosa, jQuery deve scorrere attraverso un centinaio di righe di codice (una volta ho rintracciato codice come quello sopra per vedere cosa ci faceva effettivamente jQuery). Questo è chiaramente uno spreco di tempo per tutti.

L'altro costo significativo di jQuery è il fatto che avvolge tutto all'interno di un nuovo oggetto jQuery. Questo sovraccarico è particolarmente dispendioso se è necessario scartare nuovamente l'oggetto o utilizzare uno dei metodi dell'oggetto per gestire le proprietà che sono già esposte sull'elemento originale.

Dove jQuery ha un vantaggio, tuttavia, sta nel modo in cui gestisce le raccolte. Se il requisito è impostare proprietà di più elementi, jQuery ha un eachmetodo integrato che consente qualcosa del genere:

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

Per farlo con Vanilla JavaScript richiederebbe qualcosa del genere:

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

che alcuni trovano scoraggianti.

Anche i selettori jQuery sono leggermente diversi, ma i browser moderni (escluso IE8) non otterranno molti vantaggi.

Di norma, avverto di non utilizzare jQuery per nuovi progetti:

  • jQuery è una libreria esterna che si aggiunge al sovraccarico del progetto e alla tua dipendenza da terze parti.
  • La funzione jQuery è molto costosa, in termini di elaborazione.
  • jQuery impone una metodologia che deve essere appresa e può competere con altri aspetti del codice.
  • jQuery è lento nell'esporre nuove funzionalità in JavaScript.

Se nessuna delle precedenti è importante, fai quello che vuoi. Tuttavia, jQuery non è più importante per lo sviluppo multipiattaforma come una volta, dato che i moderni JavaScript e CSS vanno molto più in là rispetto al passato.

Questo non fa menzione di altre funzionalità di jQuery. Tuttavia, penso che anche loro abbiano bisogno di uno sguardo più attento.


1
La tua sintassi non è nemmeno corretta per non menzionare le altre cose sbagliate come "esporre lentamente nuove funzionalità in Javascript" Il lavoro di JQuery non è nemmeno quello di esporre nuove funzionalità, è di rendere facile la manipolazione del DOM e fare cose semplici che potrebbero essere come 10 linee in Javascript. Tutto il tuo commento non ha alcun senso e contiene molte cose sbagliate. Valuta di migliorarlo.
Boy pro,

@Boypro Grazie per il tuo commento, ma anche questo è pieno di errori. Forse ti piacerebbe condividere ciò che riguarda la mia risposta che ti offende così tanto. Ciò che è "nemmeno corretto". Meglio ancora, potresti voler contribuire con la tua risposta. La domanda riguarda il costo dell'utilizzo di jQuery quando JavaScript vanilla può fare molto. Valuta di rispondere.
Manngo,

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

L'affare è con la funzione $ () che crea un array e poi lo scompone per te ma con document.querySelectorAll () crea un array e devi romperlo.


0

Solo un commento su questo, quando si utilizza materiale design lite, il selettore jquery non restituisce la proprietà per il design del materiale per qualche motivo.

Per:

<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>

Questo funziona:

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

Questo non:

$('#myinputfield').parentNode.MaterialTextfield.change();
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.