¿Qué devuelven los métodos querySelectorAll y getElementsBy*?

Resuelto Mohd Hasnain asked hace 12 años • 0 respuestas

¿Funcionan getElementsByClassName(y funciones similares como getElementsByTagNamey querySelectorAll) igual getElementByIdo devuelven una matriz de elementos?

La razón por la que pregunto es porque estoy intentando cambiar el estilo de todos los elementos usando getElementsByClassName. Vea abajo.

//doesn't work
document.getElementsByClassName('myElement').style.size = '100px';

//works
document.getElementById('myIdElement').style.size = '100px';
Mohd Hasnain avatar May 22 '12 06:05 Mohd Hasnain
Aceptado

Su getElementByIdcódigo funciona ya que los ID deben ser únicos y, por lo tanto, la función siempre devuelve exactamente un elemento (o nullsi no se encontró ninguno).

Sin embargo, los métodos getElementsByClassName, getElementsByName, getElementsByTagNamey getElementsByTagNameNS devuelven una colección iterable de elementos.

Los nombres de los métodos proporcionan una pista: getElementimplica singular , mientras que getElementsimplica plural .

El método querySelectortambién devuelve un único elemento y querySelectorAlluna colección iterable.

La colección iterable puede ser a NodeListo HTMLCollection.

getElementsByNamey querySelectorAllambos están especificados para devolver un NodeList; los otros getElementsBy*métodos están especificados para devolver un HTMLCollection, pero tenga en cuenta que algunas versiones de navegador implementan esto de manera diferente.

Ambos tipos de colecciones no ofrecen las mismas propiedades que ofrecen los Elementos, Nodos o tipos similares; es por eso que la lectura stylede document.getElements... (... )falla. En otras palabras: a NodeListo an HTMLCollectionno tiene a style; sólo un Elementtiene un style.


Estas colecciones "similares a matrices" son listas que contienen cero o más elementos, sobre los cuales es necesario iterar para poder acceder a ellas. Si bien puedes iterar sobre ellos de manera similar a una matriz, ten en cuenta que son diferentes de Arrays .

En los navegadores modernos, puede convertir estos iterables en una matriz adecuada con Array.from; entonces puedes usar forEachotros métodos de matriz, por ejemplo, métodos de iteración :

Array.from(document.getElementsByClassName("myElement"))
  .forEach((element) => element.style.size = "100px");

En navegadores antiguos que no admiten Array.fromlos métodos de iteración, aún puedes usar Array.prototype.slice.call. Luego puedes iterar sobre él como lo harías con una matriz real:

var elements = Array.prototype.slice
    .call(document.getElementsByClassName("myElement"));

for(var i = 0; i < elements.length; ++i){
  elements[i].style.size = "100px";
}

También puede iterar sobre NodeListo HTMLCollectionmismo, pero tenga en cuenta que, en la mayoría de las circunstancias, estas colecciones están activas ( documentos MDN , especificaciones DOM ), es decir, se actualizan a medida que cambia el DOM. Entonces, si inserta o elimina elementos mientras realiza el bucle, asegúrese de no omitir accidentalmente algunos elementos ni crear un bucle infinito . La documentación de MDN siempre debe indicar si un método devuelve una colección activa o estática.

Por ejemplo, a NodeListofrece algunos métodos de iteración, como forEachen los navegadores modernos:

document.querySelectorAll(".myElement")
  .forEach((element) => element.style.size = "100px");

forTambién se puede utilizar un bucle simple :

var elements = document.getElementsByClassName("myElement");

for(var i = 0; i < elements.length; ++i){
  elements[i].style.size = "100px";
}

Aparte: .childNodesproduce un live NodeList y .childrenproduce un live HTMLCollection , por lo que estos dos captadores también deben manejarse con cuidado.


Hay algunas bibliotecas como jQuery que acortan un poco las consultas DOM y crean una capa de abstracción sobre "un elemento" y "una colección de elementos":

$(".myElement").css("size", "100px");
ThiefMaster avatar May 21 '2012 23:05 ThiefMaster

Estás usando una matriz como objeto, la diferencia entre getElementbyIdy getElementsByClassNamees que:

  • getElementbyIddevolverá un objeto Elemento o nulo si no se encuentra ningún elemento con el ID
  • getElementsByClassNamedevolverá una HTMLCollection activa , posiblemente de longitud 0 si no se encuentran elementos coincidentes

getElementsByClassName

El getElementsByClassName(classNames)método toma una cadena que contiene un conjunto desordenado de tokens únicos separados por espacios que representan clases. Cuando se llama, el método debe devolver un NodeListobjeto activo que contenga todos los elementos del documento que tengan todas las clases especificadas en ese argumento, habiendo obtenido las clases dividiendo una cadena en espacios. Si no se especifican tokens en el argumento, el método debe devolver una NodeList vacía.

https://www.w3.org/TR/2008/WD-html5-20080610/dom.html#getelementsbyclassname

obtenerElementoPorId

El método getElementById() accede al primer elemento con la identificación especificada.

https://developer.mozilla.org/en-US/docs/Web/API/Document/getElementById

en tu código las líneas:

1- document.getElementsByClassName('myElement').style.size = '100px';

NO funcionará como se esperaba, porque getElementByClassNamedevolverá una matriz, y la matriz NO tendrá la stylepropiedad, puede acceder a cada una elementiterando a través de ellas.

Es por eso que la función getElementByIdfuncionó para usted, esta función devolverá el objeto directo. Por lo tanto podrá acceder a la stylepropiedad.

Alvaro Silvino avatar Feb 15 '2016 02:02 Alvaro Silvino

La siguiente descripción está tomada de esta página :

El método getElementsByClassName() devuelve una colección de todos los elementos del documento con el nombre de clase especificado, como un objeto NodeList.

El objeto NodeList representa una colección de nodos. Se puede acceder a los nodos mediante números de índice. El índice comienza en 0.

Consejo: puede usar la propiedad de longitud del objeto NodeList para determinar la cantidad de elementos con un nombre de clase específico, luego puede recorrer todos los elementos y extraer la información que desee.

Entonces, como parámetro getElementsByClassNameaceptaría un nombre de clase.

Si este es tu cuerpo HTML:

<div id="first" class="menuItem"></div>
<div id="second" class="menuItem"></div>
<div id="third" class="menuItem"></div>
<div id="footer"></div>

luego var menuItems = document.getElementsByClassName('menuItem')devolvería una colección (no una matriz) de los 3 <div>s superiores, ya que coinciden con el nombre de clase dado.

Luego puede iterar sobre esta <div>colección de nodos (s en este caso) con:

for (var menuItemIndex = 0 ; menuItemIndex < menuItems.length ; menuItemIndex ++) {
   var currentMenuItem = menuItems[menuItemIndex];
   // do stuff with currentMenuItem as a node.
}

Consulte esta publicación para obtener más información sobre las diferencias entre elementos y nodos.

guysigner avatar Jan 07 '2016 09:01 guysigner

En otras palabras

  • document.querySelector()selecciona solo el primer elemento del selector especificado. Entonces no muestra una matriz, es un valor único. Similar a document.getElementById()which recupera solo elementos de identificación, ya que las identificaciones deben ser únicas.

  • document.querySelectorAll()selecciona todos los elementos con el selector especificado y los devuelve en una matriz. Similar a solo document.getElementsByClassName()para clases y document.getElementsByTagName()etiquetas.


¿Por qué utilizar querySelector?

Se utiliza únicamente con el único propósito de facilitar y brevedad.


¿Por qué utilizar getElement/sBy?*

Rendimiento más rápido.


¿A qué se debe esta diferencia de rendimiento?

Ambas formas de selección tienen el propósito de crear una NodeList para su uso posterior. querySelectors genera una NodeList estática con los selectores, por lo que primero debe crearse desde cero.
getElement/sBy* adapta inmediatamente la NodeList activa existente del DOM actual.

Entonces, cuándo usar qué método depende de usted/su proyecto/su dispositivo.


Información

Demostración de todos los métodos Prueba de rendimiento
de la documentación de NodeList

Thielicious avatar Oct 23 '2017 11:10 Thielicious