jQuery vs document.querySelectorAll

161

Escuché varias veces que el activo más fuerte de jQuery es la forma en que consulta y manipula elementos en el DOM: puede usar consultas CSS para crear consultas complejas que serían muy difíciles de hacer en JavaScript normal. Sin embargo, hasta donde yo sé, puede lograr el mismo resultado con document.querySelectoro document.querySelectorAll, que son compatibles con Internet Explorer 8 y versiones posteriores.

Entonces la pregunta es esta: ¿por qué 'arriesgar' los gastos generales de jQuery si su activo más fuerte se puede lograr con JavaScript puro?

Sé que jQuery tiene más que solo selectores de CSS, por ejemplo, navegador cruzado AJAX, buena vinculación de eventos, etc. ¡Pero su parte de consulta es una parte muy importante de la fortaleza de jQuery!

¿Alguna idea?

Joel_Blum
fuente
44
(1) El recorrido / modificación DOM es mucho más rápido y fácil con jQuery. (2) Agrega sus propios selectores que no funcionarán en los querySelectormétodos. (3) Hacer llamadas AJAX es mucho más rápido y fácil con jQuery. (4) Soporte en IE6 +. Estoy seguro de que hay muchos más puntos que podrían hacerse también.
James Allardice
12
(5) ... la taquigrafía $ () para mecanógrafos perezosos es imprescindible.
Dexter Huinda
44
más fácil sí, ¿por qué más rápido? jQuery se traduce a javascript regular hasta donde yo sé ...
Joel_Blum
44
@ JamesAllardice— "todo ese desorden" para XMLHttpRequest entre navegadores es quizás 30 líneas de código que escribe una vez y coloca en su propia biblioteca.
RobG
66
@RobG - Sí, no digo que solo uses jQuery si eso es para lo que estás tratando de usarlo. Es solo uno de los beneficios. Si necesita un recorrido DOM sencillo, AJAX y querySelectorAll, y necesita que todo funcione en navegadores antiguos, entonces jQuery es una opción obvia. No digo que debas usarlo así .
James Allardice

Respuestas:

127

document.querySelectorAll() tiene varias inconsistencias en los navegadores y no es compatible con los navegadores más antiguos. Esto probablemente ya no cause ningún problema hoy en día . Tiene un mecanismo de alcance muy poco intuitivo y algunas otras características no tan agradables . Además, con javascript le resulta más difícil trabajar con los conjuntos de resultados de estas consultas, que en muchos casos es posible que desee hacer. jQuery proporciona funciones para trabajar en ellos como: filter(), find(), children(), parent(), map(), not()y varios más. Sin mencionar la capacidad de jQuery para trabajar con selectores de pseudo-clase.

Sin embargo, no consideraría estas cosas como las características más fuertes de jQuery, sino otras cosas como "trabajar" en el dom (eventos, estilo, animación y manipulación) de una manera compatible con crossbrowser o la interfaz ajax.

Si solo desea el motor selector de jQuery, puede usar el que está usando jQuery: Sizzle De esa manera tiene el poder del motor jQuerys Selector sin la desagradable sobrecarga.

EDITAR: Solo para el registro, soy un gran fan de JavaScript de vainilla. Sin embargo, es un hecho que a veces necesitas 10 líneas de JavaScript donde escribirías 1 línea jQuery.

Por supuesto, debes ser disciplinado para no escribir jQuery así:

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

Esto es extremadamente difícil de leer, mientras que este último es bastante claro:

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

El JavaScript equivalente sería mucho más complejo ilustrado por el pseudocódigo anterior:

1) Encuentra el elemento, considera tomar todo el elemento o solo el primero.

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

2) Itere sobre la matriz de nodos secundarios a través de algunos bucles (posiblemente anidados o recursivos) y verifique la clase (¡la lista de clases no está disponible en todos los navegadores!)

//.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) aplica el estilo CSS

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

Este código tendría al menos el doble de líneas de código que escribe con jQuery. También debería tener en cuenta los problemas entre navegadores que comprometerán la gran ventaja de velocidad (además de la confiabilidad) del código nativo.

Christoph
fuente
33
¿Qué tipo de inconsistencias querySelectorAlltiene entre los navegadores? ¿Y cómo usar jQuery resolvería esto, ya que jQuery usa querySelectorAll cuando está disponible?
3
Es cierto que una línea de código puede contener cadenas de códigos infinitos que pueden ser muy molestos durante la depuración.
Dexter Huinda
1
"2) iterar sobre la matriz de nodos secundarios a través de algunos bucles (posiblemente anidados o recursivos) y verificar la clase" << Esto es una mierda total. Puede usar querySelectorAll en el elemento en el paso anterior.
Vanuan
55
@Vanuan, esto podría no ser necesario, pero si hubiera leído mi respuesta a fondo, se habría dado cuenta de que querySelector tiene un grave problema de alcance que podría darle muchos falsos positivos cuando se usa de la manera que propone. Sin embargo, si bien eres libre de votar hacia arriba o hacia abajo por alguna razón delicada, creo que no es una razón para usar un lenguaje grosero.
Christoph
2
@ Christoph Como esto es fácil, agregué compatibilidad para IE8 y superior. Todavía grandes ventajas de velocidad (5-20 veces). Que el código se ejecutará más lentamente en un navegador antiguo como IE8 es simplemente una suposición errónea.
Pascalius
60

Si está optimizando su página para IE8 o más reciente, realmente debería considerar si necesita jquery o no. Los navegadores modernos tienen muchos recursos nativos que proporciona jquery.

Si le importa el rendimiento, puede obtener increíbles beneficios de rendimiento (2-10 más rápido) utilizando JavaScript nativo: http://jsperf.com/jquery-vs-native-selector-and-element-style/2

Transformé un div-tagcloud de jquery a javascript nativo (compatible con IE8 +), los resultados son impresionantes. 4 veces más rápido con solo un poco de sobrecarga.

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

Es posible que no necesite Jquery proporciona una visión general realmente agradable, que los métodos nativos reemplazan por la versión del navegador.

http://youmightnotneedjquery.com/


Apéndice: más comparaciones de velocidad de cómo los métodos nativos compiten con jquery

Pascalius
fuente
buena descripción, aunque algunos de los ejemplos de código son incorrectos ... Por ejemplo, $(el).find(selector)no es igual el.querySelectorAll(selector)y el rendimiento de los métodos nativos a menudo es bastante horrible: stackoverflow.com/q/14647470/1047823
Christoph
@ Christoph ¿Puedes explicarnos por qué crees que los métodos son diferentes? Por supuesto, hay casos extremos en los que jquery puede funcionar mejor, pero no he visto uno para DOM-Manipulación.
Pascalius
1
No es necesario dar más detalles, solo lea mi respuesta, mire el violín y el artículo al que me vinculé. Además, (al menos cajero automático) la mayoría de los métodos de matriz nativos son inferiores en velocidad en comparación con una implementación ingenua de js (como vinculé en la pregunta en mi primer comentario). Y estos no son casos extremos, sino más bien el caso estándar. Pero nuevamente, el enfoque principal de esta pregunta no era la velocidad.
Christoph
2
@ Christoph Por supuesto, estos métodos no son 100% iguales y jquery a menudo proporciona más comodidad. Actualicé la respuesta para mostrar que este es solo un caso marginal, en realidad no pude encontrar ningún otro caso en el que jquery funcionó mejor. No hay un foco principal de la pregunta.
Pascalius
+1 Excelente respuesta! He estado reemplazando lentamente el antiguo código de jQuery con JavaScript sin formato durante los últimos 4 o 5 años donde y cuando sea posible. Por supuesto, jQuery es excelente para algunas cosas y lo uso para esas cosas cuando siento que obtengo un beneficio sólido.
Sí Barry
13

Para entender por qué jQuery es tan popular, ¡es importante entender de dónde venimos!

Hace aproximadamente una década, los principales navegadores eran IE6, Netscape 8 y Firefox 1.5. En aquellos días, había pequeñas formas de navegador cruzado para seleccionar un elemento del DOM además Document.getElementById().

Entonces, cuando jQuery fue lanzado en 2006 , fue bastante revolucionario. En aquel entonces, jQuery estableció el estándar sobre cómo seleccionar / cambiar fácilmente elementos HTML y desencadenar eventos, porque su flexibilidad y compatibilidad con el navegador no tenían precedentes.

Ahora, más de una década después, muchas características que hicieron que jQuery fuera tan popular se han incluido en el estándar javaScript:

En general, estos no estaban disponibles en 2005. El hecho de que lo estén hoy obviamente plantea la pregunta de por qué deberíamos usar jQuery. Y, de hecho, la gente se pregunta cada vez más si deberíamos usar jQuery .

Entonces, si crees que entiendes JavaScript lo suficientemente bien como para prescindir de jQuery, ¡hazlo! ¡No te sientas obligado a usar jQuery, solo porque muchos otros lo están haciendo!

John Slegers
fuente
7

Eso es porque jQuery puede hacer mucho más que querySelectorAll.

En primer lugar, jQuery (y Sizzle, en particular), funciona para navegadores más antiguos como IE7-8 que no admiten selectores CSS2.1-3.

Además, Sizzle (que es el motor de selección detrás de jQuery) le ofrece muchos instrumentos de selección más avanzados, como la :selectedpseudoclase, un :not()selector avanzado , una sintaxis más compleja, $("> .children")etc.

Y lo hace en todos los navegadores, sin problemas, ofreciendo todo lo que jQuery puede ofrecer (complementos y API).

Sí, si cree que puede confiar en simples selectores de clase e identificación, jQuery es demasiado para usted y estaría pagando una recompensa exagerada. Pero si no lo hace y desea aprovechar todas las bondades de jQuery, úsela.

MaxArt
fuente
7

El motor selector de jQuery Sizzle se puede usar querySelectorAllsi está disponible. También suaviza las inconsistencias entre los navegadores para lograr resultados uniformes. Si no desea usar todo jQuery, puede usar Sizzle por separado. Esta es una rueda fundamental para inventar.

Aquí hay algunas selecciones de cerezas de la fuente que muestran el tipo de cosas que jQuery (con Sizzle) resuelve para usted:

Modo de peculiaridades de 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 ese guardia falla, usa una versión de Sizzle que no está mejorada querySelectorAll. Más abajo hay identificadores específicos para inconsistencias en IE, Opera y el navegador 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 );
  }

Y si todo lo demás falla, devolverá el resultado de oldSizzle(query, context, extra, seed).

KGZM
fuente
6

En términos de mantenimiento del código, hay varias razones para seguir con una biblioteca ampliamente utilizada.

Uno de los principales es que están bien documentados y tienen comunidades como ... digamos ... stackexchange, donde se puede encontrar ayuda con las bibliotecas. Con una biblioteca codificada personalizada, tiene el código fuente, y tal vez un documento de instrucciones, a menos que el (los) codificador (es) pasen más tiempo documentando el código que escribiéndolo, lo cual es muy raro.

Escribir su propia biblioteca podría funcionar para usted , pero al pasante que se sienta en el escritorio de al lado puede ser más fácil ponerse al día con algo como jQuery.

Llámalo efecto de red si quieres. Esto no quiere decir que el código será superior en jQuery; solo que la naturaleza concisa del código hace que sea más fácil comprender la estructura general para los programadores de todos los niveles de habilidad, aunque solo sea porque hay más código funcional visible a la vez en el archivo que está viendo. En este sentido, 5 líneas de código son mejores que 10.

En resumen, veo los principales beneficios de jQuery como código conciso y ubicuidad.

Dom Day
fuente
6

Aquí hay una comparación si quiero aplicar el mismo atributo, por ejemplo, ocultar todos los elementos de la clase "my-class". Esta es una razón para usar 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 ya tan popular, deberían haber hecho que document.querySelector () se comportara como $ (). En su lugar, document.querySelector () solo selecciona el primer elemento coincidente, lo que lo hace útil hasta la mitad.

Steven
fuente
44
Haría un .forEach aquí.
Phillip Senn el
Bueno, siempre puedes ir con una ruta más fácil document.querySelectorAll('.my-class').forEach(el => el.style.display = 'none');. Aún así, aunque sea más corto, el rendimiento en términos nativos siempre es mejor.
Alain Cruz
Desde el punto de vista del usuario, todo lo que sucede en menos de 0.1 segundos ocurre inmediatamente. Por lo tanto, nativo incluso es más rápido, mejor solo en caso de que la implementación de jQuery sea más lenta que 0.1 segundos. Y en la aplicación del mundo real nunca es el caso.
Yurin
3

como dice el sitio oficial: "jQuery: The Write Less, Do More, JavaScript Library"

intente traducir el siguiente código jQuery sin ninguna biblioteca

$("p.neat").addClass("ohmy").show("slow");
simon xu
fuente
1
Estoy de acuerdo con eso, sin embargo, ¿qué pasa con la legibilidad? ¿Cómo puede documentar largas líneas de código con muchas cosas no relacionadas? ¿Cómo puedes depurar tales monstruosidades?
Joel_Blum
@ user1032663 es cuestión de convenciones de documentación.
Christoph
1
La alternativa a jQuery (o cualquier biblioteca "popular" que elija) no es escribir todo desde cero, sino usar una biblioteca que se adapte a su propósito y esté bien escrita. Es posible que haya escrito partes usted mismo o haya elegido una biblioteca modular como MyLibrary para incluir solo lo que necesita.
RobG
2
El ejemplo que ha elegido realmente no prueba su punto: la pregunta es buscar diferencias en la provincia del "selector". addClass()y show()realmente no cuentan. Y en cuanto a $('p.neat'), puedes echar un vistazo a querySelector / All.
kumarharsh
document.querySelectorAll('p.neat').forEach(p=>p.classList.add('ohmy'));y deja que CSS haga el resto. Código un poco más largo, pero mucho más eficiente. Por supuesto, su solución no estaba tan disponible en los días de Legacy IE. La parte de "Hacer más" es irónica. jQuery toma alrededor de cien líneas de código para encontrar algo, por lo que hacer más no siempre es productivo.
Manngo
2

Creo que la verdadera respuesta es que jQuery se desarrolló mucho antes de querySelector/querySelectorAllestar disponible en todos los principales navegadores.

El lanzamiento inicial de jQuery fue en 2006 . De hecho, incluso jQuery no fue el primero en implementar los selectores CSS .

IE fue el último navegador en implementar querySelector/querySelectorAll. Su octava versión fue lanzada en 2009 .

Ahora, los selectores de elementos DOM ya no son el punto más fuerte de jQuery. Sin embargo, todavía tiene muchos beneficios bajo la manga, como accesos directos para cambiar el contenido css y html del elemento, animaciones, eventos vinculantes, ajax.

Vanuan
fuente
1

Antigua pregunta, pero media década después, vale la pena volver a visitarla. Aquí solo estoy discutiendo el aspecto del selector de jQuery.

document.querySelector[All]es compatible con todos los navegadores actuales, hasta IE8, por lo que la compatibilidad ya no es un problema. Tampoco he encontrado problemas de rendimiento para hablar (se suponía que era más lento que document.getElementById, pero mis propias pruebas sugieren que es un poco más rápido).

Por lo tanto, cuando se trata de manipular un elemento directamente, es preferible a jQuery.

Por ejemplo:

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

es muy superior a:

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

Para hacer cualquier cosa, jQuery tiene que ejecutar un centenar de líneas de código (una vez tracé un código como el anterior para ver qué estaba haciendo realmente jQuery con él). Esto es claramente una pérdida de tiempo para todos.

El otro costo significativo de jQuery es el hecho de que envuelve todo dentro de un nuevo objeto jQuery. Esta sobrecarga es particularmente derrochadora si necesita desenvolver el objeto nuevamente o usar uno de los métodos del objeto para tratar las propiedades que ya están expuestas en el elemento original.

Sin embargo, donde jQuery tiene una ventaja es en cómo maneja las colecciones. Si el requisito es establecer propiedades de múltiples elementos, jQuery tiene un eachmétodo incorporado que permite algo como esto:

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

Hacerlo con Vanilla JavaScript requeriría algo como esto:

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

que algunos encuentran desalentador.

Los selectores de jQuery también son ligeramente diferentes, pero los navegadores modernos (excluyendo IE8) no obtendrán muchos beneficios.

Como regla, advierto contra el uso de jQuery para nuevos proyectos:

  • jQuery es una biblioteca externa que se suma a la sobrecarga del proyecto y a su dependencia de terceros.
  • La función jQuery es muy costosa, en cuanto al procesamiento.
  • jQuery impone una metodología que necesita ser aprendida y puede competir con otros aspectos de su código.
  • jQuery tarda en exponer nuevas funciones en JavaScript.

Si nada de lo anterior importa, entonces haz lo que quieras. Sin embargo, jQuery ya no es tan importante para el desarrollo multiplataforma como solía serlo, ya que JavaScript y CSS modernos van mucho más allá de lo que solían ser.

Esto no menciona otras características de jQuery. Sin embargo, creo que ellos también necesitan una mirada más cercana.

Manngo
fuente
1
Su sintaxis ni siquiera es correcta sin mencionar las otras cosas incorrectas como "lento para exponer nuevas características en Javascript" El trabajo de JQuery ni siquiera es exponer nuevas características, es facilitarle la manipulación DOM y hacer cosas simples que podrían ser como 10 líneas en Javascript. Todo tu comentario simplemente no tiene ningún sentido y tiene muchas cosas equivocadas. Considera mejorarlo.
Boy pro
@Boypro Gracias por tu comentario, pero también está lleno de errores. Quizás te gustaría compartir de qué se trata mi respuesta que tanto te ofende. Lo que "ni siquiera es correcto". Mejor aún, le gustaría contribuir con su propia respuesta. La pregunta es sobre el costo de usar jQuery cuando JavaScript vainilla puede hacer mucho. Considera responderlo.
Manngo
0
$ ("# id") vs document.querySelectorAll ("# id")

El acuerdo es con la función $ (), crea una matriz y luego la divide por usted, pero con document.querySelectorAll () crea una matriz y debe dividirla.


fuente
0

Solo un comentario sobre esto, cuando se usa material design lite, jquery selector no devuelve la propiedad para el diseño de material por alguna razón.

Por:

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

Esto funciona:

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

Esto no lo hace:

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