Saltar al contenido

querySelector y querySelectorAll vs getElementsByClassName y getElementById en JavaScript

Posterior a buscar en diversos repositorios y foros al final hemos dado con la respuesta que te enseñaremos más adelante.

Solución:

Me gustaría saber cuál es exactamente la diferencia entre querySelector y querySelectorAll contra getElementsByClassName y getElementById.

La sintaxis y la compatibilidad del navegador.

querySelector es más útil cuando desea utilizar selectores más complejos.

Por ejemplo, todos los elementos de la lista descienden de un elemento que es miembro de la clase foo: .foo li

document.querySelector (“# view: _id1: inputText1”) no funciona. Pero escribir document.getElementById (“view: _id1: inputText1”) funciona. ¿Alguna idea de por qué?

los : El carácter tiene un significado especial dentro de un selector. Tienes que escapar de ella. (El carácter de escape del selector tiene un significado especial en un JS string también, así que tienes que escapar ese también).

document.querySelector("#view\:_id1\:inputText1")

recopilación de la documentación de Mozilla:

La interfaz NodeSelector Esta especificación agrega dos métodos nuevos a cualquier objeto que implemente las interfaces Document, DocumentFragment o Element:

querySelector

Devuelve el primer nodo de elemento coincidente dentro del subárbol del nodo. Si no se encuentra ningún nodo coincidente, null es regresado.

querySelectorAll

Devuelve un NodeList que contiene todos los elementos coincidentes nodos dentro del subárbol del nodo, o una NodeList vacía si no se encuentran coincidencias.

y

Nota: NodeList devuelto por querySelectorAll() no está en vivo, lo que significa que los cambios en el DOM no se reflejan en la colección. Esto es diferente de otros métodos de consulta DOM que devuelven listas de nodos en vivo.

Para esta respuesta, me refiero a querySelector y querySelectorAll como querySelector * y para getElementById, getElementsByClassName, getElementsByTagName, y getElementsByName como getElement *.

Diferencias principales

  1. querySelector * es más flexible, ya que puede pasarle cualquier selector CSS3, no solo los simples para id, etiqueta o clase.
  2. El rendimiento de querySelector cambia con el tamaño del DOM en el que se invoca.* Para ser precisos, las llamadas querySelector * se ejecutan en tiempo O (n) y las llamadas getElement * se ejecutan en tiempo O (1), donde n es el número total de todos los hijos del elemento o documento en el que se invoca. Este hecho parece ser el menos conocido, así que lo voy a poner en negrita.
  3. Las llamadas getElement * devuelven referencias directas al DOM, mientras que querySelector * realiza internamente copias de los elementos seleccionados antes de devolver referencias a ellos. Estos se conocen como “en vivo” y “static”respectivamente. Esto NO está estrictamente relacionado con los tipos que devuelven. No conozco ninguna forma de saber si un elemento está activo o static programáticamente, ya que depende de si el elemento se copió en algún momento y no es una propiedad intrínseca de los datos. Los cambios en los elementos en vivo se aplican de inmediato: cambiar un elemento en vivo lo cambia directamente en el DOM y, por lo tanto, la siguiente línea de JS puede ver ese cambio y se propaga a cualquier otro elemento en vivo que haga referencia a ese elemento de inmediato. Cambios a static los elementos solo se vuelven a escribir en el DOM después de que se termina de ejecutar el script actual. Estos pasos adicionales de copia y escritura tienen un efecto pequeño, y generalmente insignificante, en el rendimiento.
  4. Los tipos de devolución de estas llamadas varían. querySelector y getElementById ambos devuelven un solo elemento. querySelectorAll y getElementsByName ambos devuelven NodeLists, que son funciones más nuevas que se agregaron después de que HTMLCollection pasó de moda. El mas viejo getElementsByClassName y getElementsByTagName ambos devuelven HTMLCollections. Una vez más, esto es esencialmente irrelevante para si los elementos están vivos o static.

Estos conceptos se resumen en la siguiente tabla.

Function               | Live? | Type           | Time Complexity
querySelector          |   N   | Element        |  O(n)
querySelectorAll       |   N   | NodeList       |  O(n)
getElementById         |   Y   | Element        |  O(1)
getElementsByClassName |   Y   | HTMLCollection |  O(1)
getElementsByTagName   |   Y   | HTMLCollection |  O(1)
getElementsByName      |   Y   | NodeList       |  O(1)

Detalles, consejos y ejemplos

  • Las colecciones de HTMLC no son tan array-como como NodeLists y no es compatible con .forEach (). Encuentro que el operador de propagación es útil para solucionar esto:

    [...document.getElementsByClassName("someClass")].forEach()

  • Cada elemento, y el global document, tenga acceso a todas estas funciones excepto para getElementById y getElementsByName, que solo se implementan en document.

  • Encadenar llamadas getElement * en lugar de utilizar querySelector * mejorará el rendimiento, especialmente en DOM muy grandes. Incluso en DOM pequeños y / o con cadenas muy largas, generalmente es más rápido. Sin embargo, a menos que sepa que necesita el rendimiento, debería preferirse la legibilidad de querySelector *. querySelectorAll a menudo es más difícil de reescribir, porque debe seleccionar elementos de NodeList o HTMLCollection en cada paso. Por ejemplo, el siguiente código no no trabaja:

    document.getElementsByClassName("someClass").getElementsByTagName("div")

    porque solo puede usar getElements * en elementos individuales, no en colecciones. Por ejemplo:

    document.querySelector("#someId .someClass div")

    podría escribirse como:

    document.getElementById("someId").getElementsByClassName("someClass")[0].getElementsByTagName("div")[0]

    Tenga en cuenta el uso de [0] para obtener solo el primer elemento de la colección en cada paso que devuelve una colección, lo que da como resultado un elemento al final al igual que con querySelector.

  • Dado que todos los elementos tienen acceso a las llamadas querySelector * y getElement *, puede hacer cadenas usando ambas llamadas, lo que puede ser útil si desea obtener alguna ganancia de rendimiento, pero no puede evitar un querySelector que no se puede escribir en términos de las llamadas getElement * .

  • Aunque generalmente es fácil saber si un selector se puede escribir usando solo llamadas getElement *, hay un caso que puede no ser obvio:

    document.querySelectorAll(".class1.class2")

    se puede reescribir como

    document.getElementsByClassName("class1 class2")

  • Usando getElement * en un static elemento obtenido con querySelector * dará como resultado un elemento que está activo con respecto al static subconjunto del DOM copiado por querySelector, pero no vivo con respecto al documento completo DOM … aquí es donde el simple live /static La interpretación de los elementos comienza a desmoronarse. Probablemente debería evitar situaciones en las que tenga que preocuparse por esto, pero si lo hace, recuerde que las llamadas querySelector * copian los elementos que encuentran antes de devolver referencias a ellos, pero las llamadas getElement * obtienen referencias directas sin copiar.

  • Ninguna API especifica qué elemento debe seleccionarse primero si hay varias coincidencias.

  • Debido a que querySelector * itera a través del DOM hasta que encuentra una coincidencia (ver Diferencia principal # 2), lo anterior también implica que no puede confiar en la posición de un elemento que está buscando en el DOM para garantizar que se encuentre rápidamente: el El navegador puede iterar a través del DOM hacia atrás, hacia adelante, primero la profundidad, primero la amplitud o de otra manera. getElement * seguirá encontrando elementos aproximadamente en la misma cantidad de tiempo independientemente de su ubicación.

Reseñas y valoraciones del post

Si sostienes alguna duda o forma de aclarar nuestro sección te inspiramos realizar una reseña y con mucho placer lo ojearemos.

¡Haz clic para puntuar esta entrada!
(Votos: 0 Promedio: 0)


Tags : /

Utiliza Nuestro Buscador

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *