204 votes

Que renvoient les méthodes querySelectorAll et getElementsBy* ?

Haga getElementsByClassName (et des fonctions similaires comme getElementsByTagName y querySelectorAll ) fonctionnent de la même manière que getElementById ou renvoient-ils un tableau d'éléments ?

La raison de ma question est que j'essaie de modifier le style de tous les éléments à l'aide de la fonction getElementsByClassName . Voir ci-dessous.

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

//works
document.getElementById('myIdElement').style.size = '100px';

197voto

ThiefMaster Points 135805

Votre getElementById fonctionne puisque les ID doivent être uniques et que la fonction renvoie donc toujours un seul élément (ou null si aucun n'a été trouvé).

Cependant, les méthodes getElementsByClassName , getElementsByName , getElementsByTagName et getElementsByTagNameNS retourne une collection itérable d'éléments.

Les noms des méthodes fournissent un indice : getElement implica singulier alors que getElements implica au pluriel .

La méthode querySelector renvoie également un seul élément, et querySelectorAll renvoie une collection itérable.

La collection itérable peut être soit un NodeList ou un HTMLCollection .

getElementsByName y querySelectorAll sont toutes deux spécifiées pour retourner un NodeList ; l'autre getElementsBy* méthodes sont spécifiés pour retourner un HTMLCollection mais veuillez noter que certaines versions du navigateur l'implémentent différemment.

Ces deux types de collections n'offrent pas les mêmes propriétés que les Éléments, les Nœuds ou d'autres types similaires ; c'est pourquoi la lecture de style de document.getElements ( ) échoue. En d'autres termes, un NodeList ou un HTMLCollection n'a pas de style ; seulement un Element a un style .


Ces collections "de type tableau" sont des listes qui contiennent zéro ou plusieurs éléments, sur lesquels vous devez itérer afin d'y accéder. Bien que vous puissiez les itérer de la même manière qu'un tableau, notez qu'elles sont différents de Array s .

Dans les navigateurs modernes, vous pouvez convertir ces itérables en un véritable tableau à l'aide de la commande Array.from ; alors vous pouvez utiliser forEach et autres Méthodes de tableau, par exemple méthodes d'itération :

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

Dans les anciens navigateurs qui ne prennent pas en charge Array.from ou les méthodes d'itération, vous pouvez toujours utiliser Array.prototype.slice.call . Ensuite, vous pouvez itérer sur le tableau comme vous le feriez avec un vrai tableau :

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

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

Vous pouvez également itérer sur les NodeList ou HTMLCollection en soi, mais sachez que dans la plupart des cas, ces collectes sont en direct ( Documents MDN , DOM spec ), c'est-à-dire qu'ils sont mis à jour au fur et à mesure que le DOM change. Donc, si vous insérez ou supprimez des éléments pendant que vous bouclez, assurez-vous de ne pas accidentellement sauter des éléments ou créer une boucle infinie . La documentation MDN doit toujours indiquer si une méthode renvoie une collection vivante ou statique.

Par exemple, un NodeList propose des méthodes d'itération telles que forEach dans les navigateurs modernes :

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

Un simple for peut également être utilisé :

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

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

A part : .childNodes donne un en direct NodeList y .children donne un en direct HTMLCollection Ces deux getters doivent donc être manipulés avec précaution.


Il existe des bibliothèques comme jQuery qui rendent l'interrogation du DOM un peu plus courte et créent une couche d'abstraction sur "un élément" et "une collection d'éléments" :

$(".myElement").css("size", "100px");

26voto

Alvaro Joao Points 4546

Vous utilisez un tableau comme un objet, la différence entre getElementbyId y getElementsByClassName c'est que :

  • getElementbyId retournera un Objet élémentaire ou null si aucun élément avec l'ID n'est trouvé
  • getElementsByClassName retournera un live HTMLCollection éventuellement de longueur 0 si aucun élément correspondant n'est trouvé.

getElementsByClassName

El getElementsByClassName(classNames) prend une chaîne de caractères qui contient un ensemble non ordonné de jetons uniques séparés par des espaces représentant des classes. Lorsqu'elle est appelée, la méthode doit retourner un NodeList contenant tous les éléments du document qui qui ont toutes les classes spécifiées dans cet argument, en ayant obtenu l'information suivante classes en divisant une chaîne de caractères sur les espaces. S'il n'y a pas de tokens spécifié dans l'argument, alors la méthode doit retourner une NodeList.

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

getElementById

La méthode getElementById() permet d'accéder au premier élément ayant l'identifiant spécifié.

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

dans votre code les lignes :

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

sera PAS fonctionnent comme prévu, car le getElementByClassName retournera un tableau, et le tableau sera PAS ont le style vous pouvez accéder à chaque element en les parcourant par itération.

C'est pourquoi la fonction getElementById a fonctionné pour vous, cette fonction retournera l'objet direct. Vous pourrez donc accéder à l'objet style propriété.

16voto

kind user Points 20108

ES6 fournit Array.from() qui crée une nouvelle instance de tableau à partir d'un objet de type tableau ou itérable.

let boxes = document.getElementsByClassName('box');

Array.from(boxes).forEach(v => v.style.background = 'green');
console.log(Array.from(boxes));

.box {
  width: 50px;
  height: 50px;
  margin: 5px;
  background: blue;
  display: inline-block;
}

<div class='box'></div>
<div class='box'></div>
<div class='box'></div>
<div class='box'></div>

Comme vous pouvez le voir dans l'extrait de code, après avoir utilisé l'option Array.from() vous pouvez alors manipuler chaque élément.

La même solution en utilisant jQuery .

$('.box').css({'background':'green'});

.box {
  width: 50px;
  height: 50px;
  margin: 5px;
  background: blue;
  display: inline-block;
}

<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class='box'></div>
<div class='box'></div>
<div class='box'></div>
<div class='box'></div>

13voto

remdevtec Points 1630

La description suivante est tirée de cette page :

La méthode getElementsByClassName() renvoie une collection de tous les éléments du document avec le nom de classe spécifié, sous la forme d'un objet NodeList.

L'objet NodeList représente une collection de nœuds. Les noeuds peuvent être accessibles par des numéros d'index. L'index commence à 0.

Conseil : Vous pouvez utiliser la propriété length de l'objet NodeList pour déterminer le nombre d'éléments avec un nom de classe spécifié, puis vous pouvez boucler à travers tous les éléments et extraire les informations que vous voulez.

Ainsi, en tant que paramètre getElementsByClassName accepterait un nom de classe.

Si c'est votre corps HTML :

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

puis var menuItems = document.getElementsByClassName('menuItem') renverrait une collection (et non un tableau) des 3 éléments supérieurs de la liste. <div> s, car ils correspondent au nom de classe donné.

Vous pouvez ensuite itérer sur ces nœuds ( <div> dans ce cas) de la collection :

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

Veuillez vous référer à ce poste pour en savoir plus sur les différences entre les éléments et les nœuds.

8voto

Thielicious Points 1712

En d'autres termes

  • document.querySelector() ne sélectionne que le premier un de l'élément du sélecteur spécifié. Il ne s'agit donc pas d'un tableau, mais d'une valeur unique. Similaire à document.getElementById() qui récupère uniquement les éléments d'identification, puisque les ID doivent être uniques.

  • document.querySelectorAll() sélectionne todo avec le sélecteur spécifié et les retourne dans un tableau. Similaire à document.getElementsByClassName() pour les cours et document.getElementsByTagName() uniquement.

Pourquoi utiliser le querySelector ?

Il est utilisé dans le seul but d'être facile et bref.

Pourquoi utiliser getElement/sBy?* ?

Des performances plus rapides.

Pourquoi cette différence de performance ?

Les deux modes de sélection ont pour but de créer une Liste de nœuds pour une utilisation ultérieure. querySelectors génère une NodeList statique avec les sélecteurs, elle doit donc être d'abord créée à partir de zéro.
getElement/sBy* adapte immédiatement la NodeList vivante existante du DOM actuel.

C'est donc à vous, à votre projet et à votre appareil de décider quand utiliser telle ou telle méthode.

Infos

Démonstration de toutes les méthodes
Documentation sur les listes de nœuds
Test de performance

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X