Depuis MDN pour NodeList :
Dans certains cas, la NodeList est une collection active, ce qui signifie que les changements dans le DOM sont reflétés dans la collection. Par exemple, Node.childNodes est en ligne:
var parent = document.getElementById('parent'); var child_nodes = parent.childNodes; console.log(child_nodes.length); // let's assume "2" parent.appendChild(document.createElement('div')); console.log(child_nodes.length); // should output "3"
Dans d'autres cas, la NodeList est une collection statique, ce qui signifie que toute modification ultérieure du DOM n'affecte pas le contenu de la collection. document.querySelectorAll renvoie une NodeList statique.
Alors .... un peu ennuyeux! Existe-t-il une référence centrale pour quelles méthodes retournent des listes actives et lesquelles retournent des listes statiques, sans avoir à vérifier individuellement toutes les différentes parties de l'API DOM? Y a-t-il une règle à l'œuvre ici?
Les informations sur chaque méthode détaillent si elle est en direct ou non, mais il ne semble pas y avoir de convention standard pour la déterminer.
document.getElementsByClassName()
est un HTMLCollection
et est actif.
document.getElementsByTagName()
est un HTMLCollection
et est actif.
document.getElementsByName()
est un NodeList
et est en direct.
document.querySelectorAll()
est un NodeList
et n'est pas en direct.
HTMLCollection
s semblent toujours être en direct
Une HTMLCollection est une liste de nœuds. Un nœud individuel peut être consulté soit par un index ordinal, soit par le nom ou les attributs id du nœud.
Remarque: Les collections dans le DOM HTML sont supposées être en direct, ce qui signifie qu'elles sont automatiquement mises à jour lorsque le document sous-jacent est modifié.
http://www.w3.org/TR/DOM-Level-2-HTML/html.html#ID-75708506
Ainsi, les collections HTML sont toujours "dans le dom", alors qu'un nodeList
est une construction plus générique qui peut ou non être dans le DOM.
Un objet NodeList est une collection de nœuds ... L'interface NodeList fournit l'abstraction d'une collection ordonnée de nœuds, sans définir ni contraindre la façon dont cette collection est implémentée. Les objets NodeList dans le DOM sont actifs.
http://www.w3.org/TR/DOM-Level-3-Core/core.html#td-live
Sonne bien, non?
Une collection est un objet qui représente une liste de nœuds DOM. Une collection peut être en direct ou statique. Sauf indication contraire, une collection doit être en direct.
http://www.w3.org/TR/2012/WD-dom-20120405/#collections
Les collections statiques seront donc indiquées comme telles dans la spécification. Donc, par cette logique, document.querySelectorAll()
est une collection, mais c'est pas dans le DOM. Parce que si les collections peuvent être actives ou non, les collections in le DOM doit être actif ... Cette distinction n'est pas super utile.
Eh bien, voici une méthode rapide pour déterminer si un collection
est actif; il ajoute un clone d'un membre de la collection au DOM
(donc il correspondra au sélecteur), et vérifie si la longueur a changé, puis le supprime (donc la page n'est pas affectée)
[~ # ~] démo [~ # ~]
function isLive(collection) {
if (collection.length < 1) {
return undefined; //inconclusivw
}
let body = document.getElementsByTagName('body')[0];
let l1 = collection.length;
let clone = collection.item(0).cloneNode();
clone.style.display = "none";
body.appendChild(clone);
let l2 = collection.length;
body.removeChild(clone);
return l2 !== l1;
}
divs1 = document.getElementsByClassName('c');
console.log("document.getElementsByClassName('c'):",divs1.toString()); //"[object HTMLCollection]"
divs2 = document.querySelectorAll('.c');
console.log("document.querySelectorAll('.c'): ",divs2.toString()); //"[object NodeList]"
divs3 = document.getElementsByName('mydiv');
console.log("document.getElementsByName('mydiv'): ",divs3.toString()); //"[object NodeList"]
console.log("isLive(divs1)",isLive(divs1)); //true
console.log("isLive(divs2)",isLive(divs2)); //false
console.log("isLive(divs3)",isLive(divs3)); //true
<html>
<body>
<div class="c" name="mydiv">C1</div>
<div class="c" name="mydiv">C2</div>
</body>
</html>
Je ne sais pas s'il y a une référence centrale, mais cela article de blog dit:
document.getElementsByTagName()
,document.getElementsByTagNameNS
etdocument.getElementsByClassName()
sont les seules options disponibles qui renvoient des listes de nœuds "en direct". En regardant ces méthodes, vous pouvez être découragé, mais ne le soyez pas.