jQuery vs document.querySelectorAll

161

Ich habe mehrmals gehört, dass das stärkste Kapital von jQuery die Art und Weise ist, wie Elemente im DOM abgefragt und bearbeitet werden: Sie können CSS-Abfragen verwenden, um komplexe Abfragen zu erstellen, die in normalem Javascript sehr schwierig zu erstellen wären. Soweit ich weiß, können Sie jedoch mit document.querySelectoroder das gleiche Ergebnis erzielen document.querySelectorAll, das in Internet Explorer 8 und höher unterstützt wird.

Die Frage ist also: Warum sollte man den Overhead von jQuery riskieren, wenn sein stärkstes Kapital mit reinem JavaScript erreicht werden kann?

Ich weiß, dass jQuery mehr als nur CSS-Selektoren hat, zum Beispiel browserübergreifendes AJAX, nettes Anhängen von Ereignissen usw. Aber sein Abfrageteil ist ein sehr großer Teil der Stärke von jQuery!

Irgendwelche Gedanken?

Joel_Blum
quelle
4
(1) Das Durchlaufen / Ändern von DOMs ist mit jQuery viel schneller und einfacher. (2) Es werden eigene Selektoren hinzugefügt, die in den querySelectorMethoden nicht funktionieren . (3) Mit jQuery können Sie AJAX-Anrufe viel schneller und einfacher tätigen. (4) Unterstützung in IE6 +. Ich bin sicher, dass noch viele weitere Punkte angesprochen werden könnten.
James Allardice
12
(5) ... die Abkürzung $ () für faule Schreibkräfte ist ein Muss.
Dexter Huinda
4
einfacher ja, warum schneller? jQuery übersetzt, soweit ich weiß, in reguläres Javascript ...
Joel_Blum
4
@ JamesAllardice - "all das Durcheinander" für browserübergreifendes XMLHttpRequest besteht möglicherweise aus 30 Codezeilen , die Sie einmal schreiben und in Ihre eigene Bibliothek einfügen .
RobG
6
@RobG - Ja, ich sage nicht, dass Sie nur jQuery verwenden, wenn das alles ist, wofür Sie es verwenden möchten. Dies ist nur einer der Vorteile. Wenn Sie eine einfache DOM-Durchquerung, AJAX und querySelectorAllbenötigen und alles für die Arbeit in älteren Browsern benötigen, ist jQuery eine naheliegende Wahl. Ich sage nicht , dass Sie es verwenden sollten , wie diese .
James Allardice

Antworten:

127

document.querySelectorAll() weist mehrere Inkonsistenzen zwischen den Browsern auf und wird in älteren Browsern nicht unterstützt. Dies wird heutzutage wahrscheinlich keine Probleme mehr verursachen . Es hat einen sehr unintuitiven Scoping-Mechanismus und einige andere nicht so schöne Funktionen . Auch mit Javascript fällt es Ihnen schwerer, mit den Ergebnismengen dieser Abfragen zu arbeiten, was in vielen Fällen der Fall sein sollte. jQuery bietet Funktionen zur Arbeit an ihnen wie: filter(), find(), children(), parent(), map(), not()und einige mehr. Ganz zu schweigen von der Fähigkeit von jQuery, mit Pseudo-Klassenselektoren zu arbeiten.

Ich würde diese Dinge jedoch nicht als die stärksten Funktionen von jQuery betrachten, sondern als andere Dinge wie das "Arbeiten" am Dom (Ereignisse, Styling, Animation & Manipulation) auf Crossbrowser-kompatible Weise oder die Ajax-Oberfläche.

Wenn Sie nur die Selector-Engine von jQuery möchten, können Sie diejenige verwenden, die jQuery selbst verwendet: Sizzle Auf diese Weise haben Sie die Leistung der jQuerys Selector-Engine ohne den unangenehmen Overhead.

EDIT: Nur fürs Protokoll, ich bin ein großer Vanille-JavaScript-Fan. Es ist jedoch eine Tatsache, dass Sie manchmal 10 Zeilen JavaScript benötigen, in denen Sie 1 Zeile jQuery schreiben.

Natürlich muss man diszipliniert sein, um jQuery nicht so zu schreiben:

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

Dies ist äußerst schwer zu lesen, während letzteres ziemlich klar ist:

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

Das äquivalente JavaScript wäre weitaus komplexer, wie der obige Pseudocode zeigt:

1) Finden Sie das Element, nehmen Sie alle Elemente oder nur das erste.

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

2) Durchlaufen Sie das Array der untergeordneten Knoten über einige (möglicherweise verschachtelte oder rekursive) Schleifen und überprüfen Sie die Klasse (Klassenliste nicht in allen Browsern verfügbar!).

//.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) Wenden Sie den CSS-Stil an

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

Dieser Code besteht aus mindestens doppelt so vielen Codezeilen, die Sie mit jQuery schreiben. Außerdem müssten Sie browserübergreifende Probleme berücksichtigen, die den schwerwiegenden Geschwindigkeitsvorteil (neben der Zuverlässigkeit) des nativen Codes beeinträchtigen .

Christoph
quelle
33
Welche Inkonsistenzen gibt querySelectorAlles zwischen Browsern? Und wie würde die Verwendung von jQuery dieses Problem lösen, da jQuery verwendet, querySelectorAll wenn verfügbar?
3
Eine Codezeile kann zwar Ketten endloser Codes enthalten, was beim Debuggen sehr ärgerlich sein kann.
Dexter Huinda
1
"2) über einige (möglicherweise verschachtelte oder rekursive) Schleifen über das Array von untergeordneten Knoten iterieren und die Klasse überprüfen" << Dies ist ein totaler Mist. Sie können querySelectorAll für das Element im vorherigen Schritt verwenden.
Vanuan
5
@Vanuan Dies ist möglicherweise nicht erforderlich, aber wenn Sie meine Antwort gründlich gelesen hätten, hätten Sie bemerkt, dass querySelector ein ernstes Scoping-Problem hat, das Ihnen bei der Verwendung in der von Ihnen vorgeschlagenen Weise möglicherweise viele falsch positive Ergebnisse liefert. Obwohl Sie aus irgendeinem pingeligen Grund frei sind, nach oben oder unten zu stimmen, denke ich, dass dies kein Grund ist, unhöfliche Sprache zu verwenden.
Christoph
2
@Christoph Da dies einfach ist, habe ich Kompatibilität für IE8 und höher hinzugefügt. Immer noch enorme Geschwindigkeitsvorteile (5-20 mal). Dass der Code in alten Browsern wie IE8 langsamer läuft, ist nur eine falsche Annahme.
Pascalius
60

Wenn Sie Ihre Seite für IE8 oder neuer optimieren, sollten Sie wirklich überlegen, ob Sie jquery benötigen oder nicht. Moderne Browser verfügen nativ über viele Assets, die jquery bietet.

Wenn Sie Wert auf Leistung legen, können Sie mit nativem Javascript unglaubliche Leistungsvorteile erzielen (2-10 schneller) : http://jsperf.com/jquery-vs-native-selector-and-element-style/2

Ich habe eine div-tagcloud von jquery transformiert in natives Javascript (IE8 + kompatibel) umgewandelt. Die Ergebnisse sind beeindruckend. 4 mal schneller mit nur wenig Overhead.

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

Sie brauchen Jquery möglicherweise nicht. Sie bietet einen wirklich schönen Überblick darüber, welche nativen Methoden für welche Browserversion ersetzt werden.

http://youmightnotneedjquery.com/


Anhang: Weitere Geschwindigkeitsvergleiche, wie native Methoden mit jquery konkurrieren

Pascalius
quelle
schöne Übersicht, obwohl einige der Codebeispiele falsch sind ... ZB $(el).find(selector)ist nicht gleich el.querySelectorAll(selector)und die Leistung von nativen Methoden ist oft ziemlich schrecklich: stackoverflow.com/q/14647470/1047823
Christoph
@Christoph Kannst du näher erläutern, warum du denkst, dass die Methoden unterschiedlich sind? Natürlich gibt es Randfälle, in denen jquery eine bessere Leistung erbringen kann, aber ich habe keinen für DOM-Manipulation gesehen.
Pascalius
1
Sie müssen nicht weiter darauf eingehen, lesen Sie einfach meine Antwort, schauen Sie sich die Geige und den Artikel an, auf den ich verlinkt habe. Außerdem sind (zumindest atm) die meisten nativen Array-Methoden im Vergleich zu einer naiven js-Implementierung (wie ich in der Frage in meinem ersten Kommentar verlinkt habe) in der Geschwindigkeit schlechter. Und das sind keine Randfälle, sondern der Standardfall. Das Hauptaugenmerk dieser Frage lag jedoch nicht auf der Geschwindigkeit.
Christoph
2
@Christoph Natürlich sind diese Methoden nicht 100% gleich und jquery bietet oft mehr Komfort. Ich habe die Antwort aktualisiert, um zu zeigen, dass dies nur ein Randfall ist. Ich konnte tatsächlich keinen anderen Fall finden, in dem jquery eine bessere Leistung erbrachte. Es gibt keinen Schwerpunkt der Frage.
Pascalius
+1 Ausgezeichnete Antwort! Ich habe in den letzten 4 oder 5 Jahren langsam alten jQuery-Code durch rohes JavaScript ersetzt, wo und wann immer dies möglich ist. Natürlich ist jQuery für einige Dinge großartig und ich verwende es für diese Dinge, wenn ich das Gefühl habe, einen soliden Nutzen zu erzielen.
Ja Barry
13

Um zu verstehen, warum jQuery so beliebt ist, ist es wichtig zu verstehen, woher wir kommen!

Vor etwa einem Jahrzehnt waren IE6, Netscape 8 und Firefox 1.5 die Top-Browser. Damals gab es nur wenige browserübergreifende Möglichkeiten, ein Element aus dem DOM auszuwählenDocument.getElementById() .

Als jQuery 2006 veröffentlicht wurde , war es ziemlich revolutionär. Damals setzte jQuery den Standard für die einfache Auswahl / Änderung von HTML-Elementen und das Auslösen von Ereignissen, da seine Flexibilität und Browserunterstützung beispiellos waren.

Jetzt, mehr als ein Jahrzehnt später, sind viele Funktionen, die jQuery so beliebt gemacht haben, in den JavaScript-Standard aufgenommen worden:

Diese waren 2005 noch nicht allgemein verfügbar. Die Tatsache, dass sie heute verfügbar sind, wirft offensichtlich die Frage auf, warum wir jQuery überhaupt verwenden sollten. Und tatsächlich fragen sich die Leute zunehmend , ob wir jQuery überhaupt verwenden sollten .

Wenn Sie also der Meinung sind, dass Sie JavaScript gut genug verstehen, um auf jQuery zu verzichten, tun Sie dies bitte! Fühlen Sie sich nicht gezwungen, jQuery zu verwenden, nur weil so viele andere es tun!

John Slegers
quelle
7

Das liegt daran, dass jQuery viel mehr kann als nur querySelectorAll.

Erstens funktioniert jQuery (und insbesondere Sizzle) für ältere Browser wie IE7-8, die keine CSS2.1-3-Selektoren unterstützen.

Außerdem bietet Sizzle (die Selektor-Engine hinter jQuery) viele fortgeschrittenere Selektorinstrumente wie die :selectedPseudoklasse, einen erweiterten :not()Selektor, eine komplexere Syntax wie in $("> .children")und so weiter.

Und es funktioniert fehlerfrei über alle Browser hinweg und bietet alles, was jQuery bieten kann (Plugins und APIs).

Ja, wenn Sie der Meinung sind, dass Sie sich auf einfache Klassen- und ID-Selektoren verlassen können, ist jQuery zu viel für Sie und Sie würden eine übertriebene Auszahlung zahlen. Wenn Sie dies jedoch nicht tun und alle Vorteile von jQuery nutzen möchten, verwenden Sie es.

MaxArt
quelle
7

Die Sizzle querySelectorAll-Auswahl- Engine von jQuery kann verwendet werden, wenn sie verfügbar ist. Außerdem werden Inkonsistenzen zwischen Browsern ausgeglichen, um einheitliche Ergebnisse zu erzielen. Wenn Sie nicht alle jQuery-Dateien verwenden möchten, können Sie Sizzle auch separat verwenden. Dies ist ein ziemlich grundlegendes Rad zu erfinden.

Hier sind einige Kirschpflücken aus der Quelle, die zeigen, was jQuery (mit Sizzle) für Sie aussortiert:

Safari-Macken-Modus:

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

Wenn dieser Schutz fehlschlägt, wird eine Version von Sizzle verwendet, die nicht erweitert wurde querySelectorAll. Weiter unten gibt es spezielle Handles für Inkonsistenzen in IE, Opera und dem Blackberry-Browser.

  // 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 );
  }

Und wenn alles andere fehlschlägt, wird das Ergebnis von zurückgegeben oldSizzle(query, context, extra, seed).

KGZM
quelle
6

In Bezug auf die Wartbarkeit von Code gibt es mehrere Gründe, sich an eine weit verbreitete Bibliothek zu halten.

Eine der wichtigsten ist, dass sie gut dokumentiert sind und Communitys wie ... say ... stackexchange haben, in denen Hilfe zu den Bibliotheken gefunden werden kann. Mit einer benutzerdefinierten codierten Bibliothek haben Sie den Quellcode und möglicherweise eine Anleitung, es sei denn, die Codierer haben mehr Zeit damit verbracht, den Code zu dokumentieren als ihn zu schreiben, was verschwindend selten ist.

Das Schreiben Ihrer eigenen Bibliothek könnte für Sie funktionieren , aber der Praktikant am nächsten Schreibtisch hat es möglicherweise leichter, sich mit so etwas wie jQuery vertraut zu machen.

Nennen Sie es Netzwerkeffekt, wenn Sie möchten. Dies bedeutet nicht, dass der Code in jQuery überlegen ist. Nur dass die Prägnanz des Codes es einfacher macht, die Gesamtstruktur für Programmierer aller Schwierigkeitsgrade zu erfassen, schon allein deshalb, weil in der angezeigten Datei mehr Funktionscode auf einmal sichtbar ist. In diesem Sinne sind 5 Codezeilen besser als 10.

Zusammenfassend sehe ich die Hauptvorteile von jQuery in prägnantem Code und Allgegenwart.

Dom Day
quelle
6

Hier ist ein Vergleich, wenn ich dasselbe Attribut anwenden möchte, z. B. alle Elemente der Klasse "meine Klasse" ausblenden. Dies ist ein Grund, jQuery zu verwenden.

jQuery:

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

JavaScript:

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

Da jQuery bereits so beliebt ist, sollte document.querySelector () sich wie $ () verhalten. Stattdessen wählt document.querySelector () nur das erste übereinstimmende Element aus, wodurch es nur zur Hälfte nützlich ist.

Steven
quelle
4
Ich würde hier eine .forEach machen.
Phillip Senn
Nun, Sie können immer einen einfacheren Weg wählen document.querySelectorAll('.my-class').forEach(el => el.style.display = 'none');. Selbst wenn es kürzer ist, ist die native Leistung immer besser.
Alain Cruz
Aus Anwendersicht geschieht alles, was in weniger als 0,1 Sekunden passiert, sofort. Daher ist native sogar schneller, besser nur für den Fall, dass die jQuery-Implementierung langsamer als 0,1 Sekunden ist. Und in der Praxis ist dies niemals der Fall.
Yurin
3

wie die offizielle Seite sagt: "jQuery: Die weniger schreiben, mehr tun, JavaScript-Bibliothek"

Versuchen Sie, den folgenden jQuery-Code ohne Bibliothek zu übersetzen

$("p.neat").addClass("ohmy").show("slow");
Simon Xu
quelle
1
Ich stimme dem zu, aber was ist mit der Lesbarkeit? Wie können Sie lange Codezeilen mit vielen nicht verwandten Ereignissen dokumentieren? Wie können Sie solche Monstrositäten debuggen?
Joel_Blum
@ user1032663 das ist eine Frage der Dokumentationskonventionen.
Christoph
1
Die Alternative zu jQuery (oder einer anderen "beliebten" Bibliothek, die Sie auswählen) besteht nicht darin, alles von Grund auf neu zu schreiben, sondern eine Bibliothek zu verwenden, die Ihrem Zweck entspricht und gut geschrieben ist. Möglicherweise haben Sie selbst Teile geschrieben oder eine modulare Bibliothek wie MyLibrary ausgewählt , die nur das enthält, was Sie benötigen.
RobG
2
Das Beispiel, das Sie ausgewählt haben, beweist Ihren Standpunkt nicht wirklich: Die Frage ist die Suche nach Unterschieden in der Provinz "Selektor". addClass()und show()zähle nicht wirklich. Und wie $('p.neat')können Sie einen Blick auf querySelector / Alle haben.
Kumarshar
document.querySelectorAll('p.neat').forEach(p=>p.classList.add('ohmy'));und lassen Sie CSS den Rest erledigen. Etwas längerer Code, aber viel effizienter. Natürlich war seine Lösung in den Legacy IE-Tagen nicht so verfügbar. Der Teil „Mehr tun“ ist ironisch. jQuery benötigt ungefähr hundert Codezeilen, um etwas zu finden. Daher ist es nicht immer produktiv, mehr zu tun.
Manngo
2

Ich denke, die wahre Antwort ist, dass jQuery schon lange zuvor entwickelt wurde querySelector/querySelectorAll es in allen gängigen Browsern verfügbar war.

Die erste Veröffentlichung von jQuery erfolgte 2006 . Tatsächlich war sogar jQuery nicht der erste, der CSS-Selektoren implementierte .

IE war der letzte zu implementierende BrowserquerySelector/querySelectorAll . Die 8. Version wurde 2009 veröffentlicht .

Daher ist die Auswahl von DOM-Elementen nicht mehr die Stärke von jQuery. Es gibt jedoch noch viele Extras im Ärmel, wie Verknüpfungen zum Ändern des CSS- und HTML-Inhalts von Elementen, Animationen, Ereignisbindung und Ajax.

Vanuan
quelle
1

Alte Frage, aber ein halbes Jahrzehnt später lohnt es sich, sie noch einmal zu überdenken. Hier diskutiere ich nur den Selektoraspekt von jQuery.

document.querySelector[All]wird von allen aktuellen Browsern bis hin zu IE8 unterstützt, sodass die Kompatibilität kein Problem mehr darstellt. Ich habe auch keine nennenswerten Leistungsprobleme festgestellt (es sollte langsamer sein als document.getElementById, aber meine eigenen Tests legen nahe, dass es etwas schneller ist).

Wenn es darum geht, ein Element direkt zu bearbeiten, ist es daher jQuery vorzuziehen.

Beispielsweise:

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

ist weit überlegen:

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

Um überhaupt etwas zu tun, muss jQuery hundert Codezeilen durchlaufen (ich habe einmal Code wie den oben genannten nachverfolgt, um zu sehen, was jQuery tatsächlich damit gemacht hat). Dies ist eindeutig eine Zeitverschwendung für alle.

Die anderen erheblichen Kosten von jQuery sind die Tatsache, dass alles in ein neues jQuery-Objekt eingeschlossen wird. Dieser Overhead ist besonders verschwenderisch, wenn Sie das Objekt erneut entpacken oder eine der Objektmethoden verwenden müssen, um Eigenschaften zu verarbeiten, die bereits auf dem ursprünglichen Element verfügbar sind.

JQuery hat jedoch den Vorteil, dass es mit Sammlungen umgeht. Wenn die Anforderung ist Satz Eigenschaften mehrerer Elemente, hat jQuery eine eingebaute in eachMethode , die so etwas wie dies ermöglicht:

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

Um dies mit Vanilla JavaScript zu tun, wäre Folgendes erforderlich:

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

was manche entmutigend finden.

jQuery-Selektoren unterscheiden sich ebenfalls geringfügig, aber moderne Browser (außer IE8) profitieren nicht wesentlich.

In der Regel warne ich davor, jQuery für neue Projekte zu verwenden:

  • jQuery ist eine externe Bibliothek, die den Overhead des Projekts und Ihre Abhängigkeit von Dritten erhöht.
  • Die jQuery-Funktion ist in Bezug auf die Verarbeitung sehr teuer.
  • jQuery legt eine Methodik fest, die gelernt werden muss und mit anderen Aspekten Ihres Codes konkurrieren kann.
  • jQuery macht neue Funktionen in JavaScript nur langsam verfügbar.

Wenn keines der oben genannten Punkte von Bedeutung ist, tun Sie, was Sie wollen. JQuery ist jedoch für die plattformübergreifende Entwicklung nicht mehr so ​​wichtig wie früher, da modernes JavaScript und CSS viel weiter gehen als früher.

Andere Funktionen von jQuery werden hier nicht erwähnt. Ich denke jedoch, dass auch sie einen genaueren Blick brauchen.

Manngo
quelle
1
Ihre Syntax ist nicht einmal korrekt, ganz zu schweigen von den anderen falschen Dingen wie "Langsam neue Funktionen in Javascript verfügbar machen". JQuerys Aufgabe ist es nicht einmal, neue Funktionen verfügbar zu machen, sondern Ihnen das Manipulieren und Ausführen einfacher Dinge im DOM zu erleichtern wie 10 Zeilen in Javascript. Dein ganzer Kommentar macht einfach keinen Sinn und enthält viele falsche Dinge. Erwägen Sie, es zu verbessern.
Boy Pro
@Boypro Danke für deinen Kommentar, aber auch er ist voller Fehler. Vielleicht möchten Sie mitteilen, was Sie an meiner Antwort so sehr beleidigt. Was ist "nicht einmal richtig". Besser noch, Sie möchten vielleicht Ihre eigene Antwort einbringen. Die Frage betrifft die Kosten für die Verwendung von jQuery, wenn Vanille-JavaScript so viel kann. Erwägen Sie, darauf zu antworten.
Manngo
0
$ ("# id") vs document.querySelectorAll ("# id")

Der Deal ist mit der $ () -Funktion, die ein Array erstellt und dann für Sie auflöst, aber mit document.querySelectorAll () erstellt es ein Array und Sie müssen es auflösen.


quelle
0

Nur ein Kommentar dazu: Bei Verwendung von Material Design Lite gibt jquery selector aus irgendeinem Grund die Eigenschaft für Material Design nicht zurück.

Zum:

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

Das funktioniert:

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

Das tut nicht:

$('#myinputfield').parentNode.MaterialTextfield.change();
Ashvin Bhuttoo
quelle