mozilla
Vos résultats de recherche

    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

    Contributors to this page: taorepoara, Fredchat, uniqid
    Dernière mise à jour par : uniqid,