NodeList, Array, difference et technique de manipulation

nodelist array javascript

Dans cet article je vais vous montrer comment manipuler les elements NodeList, hérité de l’architecture DOM du navigateur. Contrairement aux Array traditionnels, les NodeList se comportent différemment, et l’iteration de ces derniers peut devenir problématique si l’on ne connaît pas les bonnes astuces.

Pour commencer nous allons simplement récupérer une liste d’élément du DOM avec un appel standard Javascript du type:

const divs = document.querySelectorAll('div');
// output: NodeList(203) [div,div,div...]

Vous pouvez essayer cette ligne de code directement dans l’inspecteur de votre navigateur pour avoir un exemple concret.

Maintenant, si je vous demande d’effectuer une action sur chaque elements retourné, vous allez certainement essayé un code de ce type:

const divs = document.querySelectorAll('div');
divs.map(element => {
  element.innerHTML = 'hello';
  return element;
});

Et vous allez vite constater que cela ne fonctionne pas. Pourquoi?? Eh bien si vous regardez attentivement le retour de console lorsque vous affichez la constants divs, vous verrez qu’il ne s’agit pas d’un tableaux Javascript mais d’une NodeList

Gestion des element DOM avec les NodeList

Voilà on commence à cerner le problème. Enfaite, une NodeList n’est pas un tableau Javascript conventionnel. C’est pour cela que les méthodes habituellement lié à l’objet Array ne sont pas disponible pour ce type d’Objet.

Mais de quel type d’Objet s’agit-il alors? Si ce n’est pas une Objet Array avec toutes les méthodes liés c’est que cet Objet est lié à l’Objet DOM. C’est un héritier du Model Objet Document et non un Objet Array traditionnel.

Les NodeList contrairement aux Array, peuvent contenir ce que nous appelons des nœuds vivant / direct… ce qui signifie que les changements effectués dans le DOM sont reflétés dans la collection. Par exemple, Node.childNodes est en direct :

var parent = document.getElementById('parent');
var child_nodes = parent.childNodes;
console.log(child_nodes.length); // supposons "2"
parent.appendChild(document.createElement('div'));
console.log(child_nodes.length); // devrait afficher "3"

Dans d’autres cas, la NodeList est une collection statique, ce qui signifie que tout changement dans le DOM n’affectera pas le contenu de la collection. document.querySelectorAll() par exemple, renvoie une NodeList statique.

Voilà l’explication bien que celle-ci ne soit pas très importante.

Bref! Nous ce que l’on veut effectuer c’est une itération de ce « tableaux » qui n’en est pas un. Donc les petit malins auront vite pensé à une autre alternative avec .forEach() ou avec une iteration du type for… of:

const divs = document.querySelectorAll('div');

// itération avec .forEach()
divs.forEach(element => {
  element.innerHTML = 'hello';
  return element;
});

// ou avec for... of
for (var element of divs) {
  element.innerHTML = 'hello';
}

Voilà! On est arrivé au résultat voulu….. mais vous pensiez que j’allais m’arrêter là?? Que j’ai écrit un article just pour cela??
NON! Je donne encore une petite astuce 😉

Convertir un NodeList en Array

En voilà une bonne astuce très pratique!! Si on peut convertir les NodeList en Array cela veut dire que l’on pourra alors utiliser les méthodes liées aux Objets Array directement pour manipuler les éléments de notre NodeList!

Aller je vous monter encore une petite technique:

const divs = document.querySelectorAll('div');

// conversion avec Array.from()
Array.from(divs).map(element => {
  element.innerHTML = 'hello';
  return element;
});

// conversion avec spread operator
[...divs].map(element => {
  element.innerHTML = 'hello';
  return element;
});

Cool non?? En utilisant Array.from() ou ls syntaxe du Spread Operator, on retrouve ainsi toutes les méthode te traitement des tableaux auquel nous sommes tellement habitué.

Support des navigateur

Encore une petite chose, lors de l’iteration ou de la conversion, vous utilisez de fonction JS qui ne sont probablement pas intégrée par tous les navigateurs. Je vous conseille donc d’utiliser un outil comme Webpack avec Babel pour normaliser votre code avant la mise en production.

Vous retrouverez tous les autres articles traitant du même sujet dans la section Programmation

Et si vous avez besoin de support pour votre projet, je vous invite vous rendre sur le lien suivant pour définir ensemble une solution de support qui vous convienne.