jQuery vs document.querySelectorAll

161

J'ai entendu à plusieurs reprises que l'atout le plus fort de jQuery est la façon dont il interroge et manipule les éléments dans le DOM: vous pouvez utiliser des requêtes CSS pour créer des requêtes complexes qui seraient très difficiles à faire en javascript classique. Cependant, pour autant que je sache, vous pouvez obtenir le même résultat avec document.querySelectorou document.querySelectorAll, qui sont pris en charge dans Internet Explorer 8 et supérieur.

La question est donc la suivante: pourquoi «risquer» les frais généraux de jQuery si son atout le plus puissant peut être atteint avec du JavaScript pur?

Je sais que jQuery a plus que de simples sélecteurs CSS, par exemple cross browser AJAX, belle attachement d'événements, etc. Mais sa partie requête est une très grande partie de la force de jQuery!

Des pensées?

Joel_Blum
la source
4
(1) La traversée / modification du DOM est beaucoup plus rapide et plus facile avec jQuery. (2) Il ajoute ses propres sélecteurs qui ne fonctionneront pas dans les querySelectorméthodes. (3) Faire des appels AJAX est beaucoup plus rapide et plus facile avec jQuery. (4) Prise en charge dans IE6 +. Je suis sûr que de nombreux autres points pourraient être soulevés.
James Allardice
12
(5) ... le raccourci $ () pour les dactylographes paresseux est un must.
Dexter Huinda
4
plus facile oui, pourquoi plus rapide? jQuery se traduit par du javascript régulier pour autant que je sache ...
Joel_Blum
4
@ JamesAllardice - "tout ce bordel" pour XMLHttpRequest inter-navigateurs est peut-être 30 lignes de code que vous écrivez une fois et que vous mettez dans votre propre bibliothèque.
RobG
6
@RobG - Ouais, je ne dis pas simplement d'utiliser jQuery si c'est tout ce que vous essayez de l'utiliser. Ce n'est qu'un des avantages. Si vous avez besoin de parcourir facilement le DOM, AJAX et querySelectorAll, et que vous avez besoin de tout cela pour fonctionner dans les anciens navigateurs, alors jQuery est un choix évident. Je ne dis pas que vous devriez l'utiliser comme ça .
James Allardice

Réponses:

127

document.querySelectorAll() présente plusieurs incohérences entre les navigateurs et n'est pas pris en charge dans les anciens navigateurs. Cela ne posera probablement plus de problèmes de nos jours . Il a un mécanisme de cadrage très peu intuitif et d'autres fonctionnalités pas si intéressantes . De plus, avec javascript, vous avez plus de mal à travailler avec les ensembles de résultats de ces requêtes, ce que vous voudrez peut-être dans de nombreux cas. jQuery fournit des fonctions pour travailler sur eux comme: filter(), find(), children(), parent(), map(), not()et plusieurs autres. Sans parler de la capacité de jQuery à travailler avec des sélecteurs de pseudo-classes.

Cependant, je ne considérerais pas ces choses comme les fonctionnalités les plus puissantes de jQuery mais d'autres choses comme "travailler" sur le dom (événements, style, animation et manipulation) d'une manière compatible crossbrowser ou l'interface ajax.

Si vous ne voulez que le moteur de sélection de jQuery, vous pouvez utiliser celui que jQuery utilise lui-même: Sizzle De cette façon, vous avez la puissance du moteur de sélection de jQuerys sans la surcharge.

EDIT: Juste pour mémoire, je suis un grand fan de JavaScript vanille. Néanmoins, c'est un fait que vous avez parfois besoin de 10 lignes de JavaScript où vous écririez 1 ligne de jQuery.

Bien sûr, vous devez être discipliné pour ne pas écrire jQuery comme ceci:

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

C'est extrêmement difficile à lire, alors que ce dernier est assez clair:

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

Le JavaScript équivalent serait beaucoup plus complexe illustré par le pseudocode ci-dessus:

1) Trouvez l'élément, envisagez de prendre tous les éléments ou seulement le premier.

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

2) Parcourez le tableau de nœuds enfants via des boucles (éventuellement imbriquées ou récursives) et vérifiez la classe (liste de classes non disponible dans tous les navigateurs!)

//.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) appliquer le style css

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

Ce code représenterait au moins deux fois plus de lignes de code que vous écrivez avec jQuery. Vous devrez également prendre en compte les problèmes inter-navigateurs qui compromettraient le sérieux avantage de vitesse (en plus de la fiabilité) du code natif.

Christoph
la source
33
Quel genre d'incohérences querySelectorAllexiste- t -il entre les navigateurs? Et comment l'utilisation de jQuery résoudrait-elle cela, puisque jQuery l' utilise querySelectorAll lorsqu'il est disponible?
3
Certes, une ligne de code peut contenir des chaînes de codes sans fin qui peuvent être très ennuyeuses lors du débogage.
Dexter Huinda
1
"2) parcourir le tableau de nœuds enfants via des boucles (éventuellement imbriquées ou récursives) et vérifier la classe" << C'est une merde totale. Vous pouvez utiliser querySelectorAll sur l'élément à l'étape précédente.
Vanuan
5
@Vanuan, ce n'est peut- être pas nécessaire, mais si vous aviez lu ma réponse attentivement, vous auriez remarqué que querySelector a un sérieux problème de portée qui pourrait vous donner beaucoup de faux positifs lorsqu'il est utilisé de la manière que vous proposez. Néanmoins, même si vous êtes libre de voter pour ou contre pour une raison délicate, je pense que ce n'est pas une raison d'utiliser un langage grossier.
Christoph
2
@Christoph Comme c'est facile, j'ai ajouté la compatibilité pour IE8 et au-dessus. Encore des avantages de vitesse énormes (5-20 fois). Que le code s'exécute plus lentement dans un ancien navigateur comme IE8 est juste une fausse hypothèse.
Pascalius
60

Si vous optimisez votre page pour IE8 ou une version plus récente, vous devez vraiment vous demander si vous avez besoin de jquery ou non. Les navigateurs modernes ont nativement de nombreux actifs fournis par jquery.

Si vous aimez les performances, vous pouvez bénéficier d'incroyables avantages en termes de performances (2 à 10 plus rapides) en utilisant le javascript natif: http://jsperf.com/jquery-vs-native-selector-and-element-style/2

J'ai transformé un div-tagcloud de jquery en javascript natif (compatible IE8 +), les résultats sont impressionnants. 4 fois plus vite avec juste un peu de frais généraux.

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

You Might Not Need Jquery fournit un très bon aperçu, quelles méthodes natives remplacent pour quelle version de navigateur.

http://youmightnotneedjquery.com/


Annexe: Autres comparaisons de vitesse sur la concurrence des méthodes natives avec jquery

Pascalius
la source
bel aperçu bien que certains exemples de code soient faux ... Par exemple, ce $(el).find(selector)n'est pas égal à el.querySelectorAll(selector)et les performances des méthodes natives sont souvent assez horribles: stackoverflow.com/q/14647470/1047823
Christoph
@Christoph Pouvez-vous expliquer pourquoi vous pensez que les méthodes sont différentes? Bien sûr, il existe des cas extrêmes où jquery peut fonctionner mieux, mais je n'en ai pas vu pour la manipulation DOM.
Pascalius
1
Inutile de préciser davantage, lisez simplement ma réponse, regardez le violon et l'article auquel j'ai lié. En outre, (au moins atm) la plupart des méthodes Array natives sont inférieures en vitesse par rapport à une implémentation js naïve (comme je l'ai lié dans la question de mon premier commentaire). Et ce ne sont pas des cas extrêmes, mais plutôt le cas standard. Mais encore une fois, l'objectif principal de cette question n'était pas la vitesse.
Christoph
2
@Christoph Bien sûr, ces méthodes ne sont pas égales à 100% et jquery offre souvent plus de commodité. J'ai mis à jour la réponse pour montrer qu'il ne s'agit que d'un cas limite, je n'ai en fait pas trouvé d'autre cas où jquery fonctionnait mieux. Il n'y a pas d'objectif principal de la question.
Pascalius le
+1 Excellente réponse! J'ai remplacé lentement l'ancien code jQuery par du JavaScript brut au cours des 4 ou 5 dernières années partout et chaque fois que possible. Bien sûr, jQuery est idéal pour certaines choses et je l'utilise pour ces choses lorsque je sens que j'en tire un avantage solide.
Oui Barry
13

Pour comprendre pourquoi jQuery est si populaire, il est important de comprendre d'où nous venons!

Il y a une dizaine d'années, les principaux navigateurs étaient IE6, Netscape 8 et Firefox 1.5. À l'époque, il y avait en outre peu de moyens multi-navigateurs pour sélectionner un élément du DOM Document.getElementById().

Ainsi, lorsque jQuery est sorti en 2006 , c'était assez révolutionnaire. À l'époque, jQuery définissait la norme pour savoir comment sélectionner / modifier facilement des éléments HTML et déclencher des événements, car sa flexibilité et la prise en charge du navigateur étaient sans précédent.

Maintenant, plus d'une décennie plus tard, de nombreuses fonctionnalités qui ont rendu jQuery si populaire sont devenues incluses dans la norme javaScript:

Ceux-ci n'étaient généralement pas disponibles en 2005. Le fait qu'ils le soient aujourd'hui soulève évidemment la question de savoir pourquoi nous devrions utiliser jQuery du tout. Et en effet, les gens se demandent de plus en plus si nous devrions utiliser jQuery .

Donc, si vous pensez que vous comprenez assez bien JavaScript pour vous passer de jQuery, faites-le! Ne vous sentez pas obligé d'utiliser jQuery, juste parce que tant d'autres le font!

John Slegers
la source
7

C'est parce que jQuery peut faire beaucoup plus que querySelectorAll.

Tout d'abord, jQuery (et Sizzle, en particulier), fonctionne pour les navigateurs plus anciens comme IE7-8 qui ne prennent pas en charge les sélecteurs CSS2.1-3.

De plus, Sizzle (qui est le moteur de sélection derrière jQuery) vous offre beaucoup d'instruments de sélection plus avancés, comme la :selectedpseudo-classe, un :not()sélecteur avancé , une syntaxe plus complexe comme dans $("> .children")et ainsi de suite.

Et il le fait entre navigateurs, parfaitement, offrant tout ce que jQuery peut offrir (plugins et API).

Oui, si vous pensez que vous pouvez compter sur de simples sélecteurs de classes et d'identifiants, jQuery est trop pour vous et vous paieriez un gain exagéré. Mais si vous ne le faites pas et que vous voulez profiter de tous les avantages de jQuery, utilisez-le.

MaxArt
la source
7

Le moteur de sélection Sizzle de jQuery peut utiliser querySelectorAlls'il est disponible. Il atténue également les incohérences entre les navigateurs pour obtenir des résultats uniformes. Si vous ne souhaitez pas utiliser tout jQuery, vous pouvez simplement utiliser Sizzle séparément. C'est une roue assez fondamentale à inventer.

Voici quelques sélections de la source qui montrent le genre de choses que jQuery (w / Sizzle) trie pour vous:

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

Si ce garde échoue, il utilise une version de Sizzle qui n'est pas améliorée avec querySelectorAll. Plus bas, il y a des poignées spécifiques pour les incohérences dans IE, Opera et le navigateur 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 );
  }

Et si tout le reste échoue, il renverra le résultat de oldSizzle(query, context, extra, seed).

KGZM
la source
6

En termes de maintenabilité du code, il existe plusieurs raisons de s'en tenir à une bibliothèque largement utilisée.

L'un des principaux est qu'ils sont bien documentés et ont des communautés telles que ... disons ... stackexchange, où de l'aide avec les bibliothèques peut être trouvée. Avec une bibliothèque codée personnalisée, vous avez le code source, et peut-être un document pratique, à moins que le (s) codeur (s) ne passe plus de temps à documenter le code qu'à l'écrire, ce qui est extrêmement rare.

Ecrire votre propre bibliothèque peut fonctionner pour vous , mais le stagiaire assis au bureau voisin peut avoir plus de facilité à se familiariser avec quelque chose comme jQuery.

Appelez cela effet de réseau si vous le souhaitez. Cela ne veut pas dire que le code sera supérieur dans jQuery; juste que la nature concise du code facilite la compréhension de la structure globale pour les programmeurs de tous les niveaux de compétence, ne serait-ce que parce qu'il y a plus de code fonctionnel visible à la fois dans le fichier que vous consultez. En ce sens, 5 lignes de code valent mieux que 10.

Pour résumer, je vois les principaux avantages de jQuery comme étant un code concis et une ubiquité.

Jour Dom
la source
6

Voici une comparaison si je veux appliquer le même attribut, par exemple masquer tous les éléments de la classe "ma-classe". C'est une des raisons d'utiliser 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';
}

Avec jQuery déjà si populaire, ils auraient dû faire en sorte que document.querySelector () se comporte exactement comme $ (). Au lieu de cela, document.querySelector () sélectionne uniquement le premier élément correspondant, ce qui le rend à moitié utile.

Steven
la source
4
Je ferais un .forEach ici.
Phillip Senn
Eh bien, vous pouvez toujours choisir un itinéraire plus facile document.querySelectorAll('.my-class').forEach(el => el.style.display = 'none');. Même s'il est plus court, le natif en termes de performances est toujours meilleur.
Alain Cruz du
Du point de vue de l'utilisateur, tout ce qui se passe en moins de 0,1 seconde se produit immédiatement. Par conséquent, le natif est encore plus rapide, meilleur uniquement dans le cas où la mise en œuvre de jQuery est plus lente que 0,1 sec. Et dans le monde réel, ce n'est jamais le cas.
yurin le
3

comme le dit le site officiel: "jQuery: The Write Less, Do More, JavaScript Library"

essayez de traduire le code jQuery suivant sans aucune bibliothèque

$("p.neat").addClass("ohmy").show("slow");
simon xu
la source
1
Je suis d'accord avec cela, mais qu'en est-il de la lisibilité? Comment pouvez-vous documenter de longues lignes de code avec beaucoup de choses non liées? Comment pouvez-vous déboguer de telles monstruosités?
Joel_Blum
@ user1032663 c'est une question de conventions de documentation.
Christoph
1
L'alternative à jQuery (ou à toute autre bibliothèque "populaire" que vous choisissez) n'est pas de tout écrire à partir de zéro, mais d'utiliser une bibliothèque qui convient à votre objectif et qui est bien écrite. Vous avez peut-être écrit des parties vous-même ou choisi une bibliothèque modulaire comme MyLibrary pour n'inclure que ce dont vous avez besoin.
RobG
2
L'exemple que vous avez choisi ne prouve pas vraiment votre point de vue: la question est de rechercher les différences dans la province «sélecteur». addClass()et show()ne compte pas vraiment. Et quant à $('p.neat'), vous pouvez jeter un oeil à querySelector / All.
kumarharsh
document.querySelectorAll('p.neat').forEach(p=>p.classList.add('ohmy'));et laissez CSS faire le reste. Code un peu plus long, mais beaucoup plus efficace. Bien sûr, sa solution n'était pas aussi disponible à l'époque de Legacy IE. La partie «Faire plus» est ironique. jQuery prend environ une centaine de lignes de code pour trouver quelque chose, donc en faire plus n'est pas toujours productif.
Manngo
2

Je pense que la vraie réponse est que jQuery a été développé bien avant querySelector/querySelectorAll être disponible dans tous les principaux navigateurs.

La première version de jQuery remonte à 2006 . En fait, même jQuery n'était pas le premier à implémenter des sélecteurs CSS .

IE a été le dernier navigateur à implémenter querySelector/querySelectorAll. Sa 8e version est sortie en 2009 .

Alors maintenant, les sélecteurs d'éléments DOM ne sont plus le point fort de jQuery. Cependant, il a encore beaucoup de bonus dans sa manche, comme des raccourcis pour changer le contenu css et html de l'élément, des animations, des liaisons d'événements, ajax.

Vanuan
la source
1

Ancienne question, mais une demi-décennie plus tard, cela vaut la peine d'être revisité. Ici, je ne parle que de l'aspect sélecteur de jQuery.

document.querySelector[All]est pris en charge par tous les navigateurs actuels, jusqu'à IE8, la compatibilité n'est donc plus un problème. Je n'ai également trouvé aucun problème de performance à proprement parler (c'était censé être plus lent que document.getElementById, mais mes propres tests suggèrent que c'est légèrement plus rapide).

Par conséquent, lorsqu'il s'agit de manipuler un élément directement, il est préférable de le préférer à jQuery.

Par exemple:

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

est largement supérieur à:

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

Pour faire quoi que ce soit, jQuery doit parcourir une centaine de lignes de code (j'ai déjà tracé un code tel que celui ci-dessus pour voir ce que jQuery faisait réellement avec). C'est clairement une perte de temps pour tout le monde.

L'autre coût important de jQuery est le fait qu'il enveloppe tout dans un nouvel objet jQuery. Cette surcharge est particulièrement inutile si vous devez à nouveau déballer l'objet ou utiliser l'une des méthodes d'objet pour traiter les propriétés déjà exposées sur l'élément d'origine.

Là où jQuery a un avantage, cependant, c'est dans la façon dont il gère les collections. Si l'exigence est de définir les propriétés de plusieurs éléments, jQuery a une eachméthode intégrée qui permet quelque chose comme ceci:

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

Pour ce faire avec Vanilla JavaScript, il faudrait quelque chose comme ceci:

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

ce que certains trouvent intimidant.

Les sélecteurs jQuery sont également légèrement différents, mais les navigateurs modernes (à l'exception d'IE8) n'en tireront pas grand chose.

En règle générale, je mets en garde contre l'utilisation de jQuery pour les nouveaux projets:

  • jQuery est une bibliothèque externe qui ajoute à la surcharge du projet et à votre dépendance à des tiers.
  • La fonction jQuery est très coûteuse, du point de vue du traitement.
  • jQuery impose une méthodologie qui doit être apprise et peut entrer en concurrence avec d'autres aspects de votre code.
  • jQuery met du temps à exposer les nouvelles fonctionnalités de JavaScript.

Si rien de ce qui précède n'a d'importance, faites ce que vous voulez. Cependant, jQuery n'est plus aussi important pour le développement multiplateforme qu'auparavant, car le JavaScript et le CSS modernes vont beaucoup plus loin qu'avant.

Cela ne fait aucune mention des autres fonctionnalités de jQuery. Cependant, je pense qu'eux aussi doivent être examinés de plus près.

Manngo
la source
1
Votre syntaxe n'est même pas correcte pour ne pas mentionner les autres choses erronées comme «lent à exposer de nouvelles fonctionnalités en Javascript» Le travail de JQuery n'est même pas d'exposer de nouvelles fonctionnalités, c'est de vous faciliter la manipulation du DOM et de faire des choses simples qui pourraient être comme 10 lignes en Javascript. Votre commentaire n'a tout simplement aucun sens et contient de nombreux éléments erronés. Pensez à l'améliorer.
Boy pro
@Boypro Merci pour votre commentaire, mais il est également plein d'erreurs. Peut-être aimeriez-vous partager ce que ma réponse vous offense tant. Ce qui est «même pas correct». Mieux encore, vous voudrez peut-être apporter votre propre réponse. La question concerne le coût d'utilisation de jQuery alors que JavaScript vanilla peut en faire autant. Pensez à y répondre.
Manngo
0
$ ("# id") vs document.querySelectorAll ("# id")

L'accord est avec la fonction $ (), il crée un tableau puis le décompose pour vous, mais avec document.querySelectorAll (), il crée un tableau et vous devez le diviser.


la source
0

Juste un commentaire à ce sujet, lors de l'utilisation de Material Design Lite, jquery selector ne renvoie pas la propriété de Material Design pour une raison quelconque.

Pour:

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

Cela marche:

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

Cela ne:

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