Please note, this is a STATIC archive of website developer.mozilla.org from November 2016, cach3.com does not collect or store any user information, there is no "phishing" involved.

NodeList

Sommaire

Les objets NodeList sont des collections de nœuds comme celles retournées par Node.childNodes et la méthode querySelectorAll.

Propriétés

length
Le nombre de nœuds dans le NodeList.

Méthodes

item ( idx )
Retourne un élément de la liste par son index ou null si l'index est en dehors des limites. Équivalent à nodeList[idx].

Description

Une collection directe

Dans certains cas, le NodeList est une collection directe. Cela signifie que les changements effectués dans le DOM sont reflétés dans la collection.

var divs = document.getElementsByTagName( 'div' );

var firstDiv = divs[ 0 ];
// firstDiv.childNodes.length === 2 par instance.

firstDiv.appendChild( document.createElement( 'div' ) ); // une autre div est ajoutée comme descendante
// le NodeList firstDiv.childNodes est automatiquement mis à jour
// firstDiv.childNodes.length === 3 instances maintenant.

Si le NodeList est la valeur retournée par document.querySelectorAll, il n'est pas direct.

Pourquoi ne puis-je pas utiliser forEach ou map sur un NodeList ?

Les NodeLists sont utilisés de la même manière que les tableaux et il est donc tentant d'utiliser des méthodes de Array.prototype sur eux, mais ils ne les implémentent pas.

Le JavaScript a un mécanisme d'héritage basé sur les prototypes pour les objets instanciés (comme les Arrays) et pour les objets hôtes (comme des NodeLists). Les instances d'Array héritent des méthodes des tableaux (comme forEach ou map) parce que leur chaîne de prototypes ressemble à ce qui suit :

myArray --> Array.prototype --> Object.prototype --> null (la chaîne de prototypes d'un objet peut être obtenue en appelant Object.getPrototypeOf plusieurs fois.)

forEach, map et d'autres sont des propriétés propres de l'objet Array.prototype.

Contrairement aux tableaux, la chaîne de prototypes des NodeLists ressemble à ce qui suit :

myNodeList --> NodeList.prototype --> Object.prototype --> null

NodeList.prototype contient la méthode item, mais aucune méthode de Array.prototype, elles ne peuvent donc pas être utilisés sur les NodeLists.

Solutions de contournement

Une idée serait d'ajouter des méthodes de Array.prototype à NodeList.prototype. Cependant, soyez conscient qu'étendre le DOM est dangereux, surtout dans les vieilles versions d'Internet Explorer (6, 7, 8).

var arrayMethods = Object.getOwnPropertyNames( Array.prototype );

arrayMethods.forEach( attachArrayMethodsToNodeList );

function attachArrayMethodsToNodeList(methodName)
{
    NodeList.prototype[methodName] = Array.prototype[methodName];
};

var divs = document.getElementsByTagName( 'div' );
var firstDiv = divs[ 0 ];

firstDiv.childNodes.forEach(function( divChild ){
  divChild.parentNode.style.color = '#0F0';
});

Une autre approche, sans extension du DOM :

var forEach = Array.prototype.forEach;

var divs = document.getElementsByTagName( 'div' );
var firstDiv = divs[ 0 ];

forEach.call(firstDiv.childNodes, function( divChild ){
  divChild.parentNode.style.color = '#0F0';
});

Notez dans l'exemple ci-dessus que passer un objet hôte (comme un NodeListv) comme this à une méthode native (comme forEach) n'est pas une garantie de bon fonctionnement avec tous les navigateurs et c'est même connu que c'est une cause d'échec avec certains.

Exemple

Il est possible de boucler sur les éléments d'un NodeList en utilisant :

for (var i = 0; i < myNodeList.length; ++i) {
  var item = myNodeList[i];  // L'appel de myNodeList.item(i) n'est pas nécessaire en JavaScript
}

Ne soyez pas tenté d'utiliser for… in ou for each… in pour énumérer les éléments de la liste, car cela énumère également la taille (length) et les propriétés du NodeList et cause des erreurs si votre script ne gère que les objets de type element. De plus, for… in ne garantit pas de visiter les propriétés dans un ordre particulier.

Les boucles for… of boucleront correctement sur les NodeList, dans les navigateurs qui supportent for… of (comme Firefox 13 et plus) :

var list = document.querySelectorAll( 'input[type=checkbox]' );
for (var item of list) {
  item.checked = true;
}

Comment convertir un NodeList en Array ?

Parfois, il est nécessaire de convertir un objet NodeList en un Array, par exemple pour utiliser une méthode spécifique d'Array. Ci-dessous, un exemple d'une technique de conversion d'un objet NodeList en un Array :

var turnObjToArray = function(obj) {
  return [].map.call(obj, function(element) {
    return element;
  })
};

var box = document.querySelectorAll('div');

var listBox = turnObjToArray(box)

Spécification

Étiquettes et contributeurs liés au document

 Contributeurs à cette page : uniqid, Fredchat, taorepoara
 Dernière mise à jour par : uniqid,