web-dev-qa-db-fra.com

Différence entre HTMLCollection, NodeLists et les tableaux d'objets

J'ai toujours été confondu entre HTMLCollections, les objets et les tableaux lorsqu'il s'agit de DOM. Par exemple...

  1. Quelle est la différence entre document.getElementsByTagName("td") et $("td")?
  2. $("#myTable") et $("td") sont des objets (objets jQuery). Pourquoi console.log affiche-t-il également le tableau des éléments DOM à côté d'eux, et ne sont-ils pas des objets et non un tableau?
  3. Qu'est-ce que les "NodeLists" insaisissables, et comment puis-je en choisir une?

Veuillez également fournir toute interprétation du script ci-dessous.

Je vous remercie

[123,"abc",321,"cba"]=[123,"abc",321,"cba"]
{123:123,abc:"abc",321:321,cba:"cba"}=Object { 123=123, abc="abc", 321=321, more...}
Node= Node { ELEMENT_NODE=1, ATTRIBUTE_NODE=2, TEXT_NODE=3, more...}
document.links= HTMLCollection[a #, a #]
document.getElementById("myTable")= <table id="myTable">
document.getElementsByClassName("myRow")= HTMLCollection[tr.myRow, tr.myRow]
document.getElementsByTagName("td")= HTMLCollection[td, td, td, td]
$("#myTable")= Object[table#myTable]
$("td")= Object[td, td, td, td]


<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> 
<html xmlns="http://www.w3.org/1999/xhtml"> 
    <head> 
        <meta http-equiv="content-type" content="text/html; charset=ISO-8859-1" /> 
        <title>Collections?</title>  
        <script src="http://code.jquery.com/jquery-latest.js" type="text/javascript"></script> 
        <script type="text/javascript">
            $(function(){
                console.log('[123,"abc",321,"cba"]=',[123,"abc",321,"cba"]);
                console.log('{123:123,abc:"abc",321:321,cba:"cba"}=',{123:123,abc:"abc",321:321,cba:"cba"});
                console.log('Node=',Node);
                console.log('document.links=',document.links);
                console.log('document.getElementById("myTable")=',document.getElementById("myTable"));
                console.log('document.getElementsByClassName("myRow")=',document.getElementsByClassName("myRow"))
                console.log('document.getElementsByTagName("td")=',document.getElementsByTagName("td"));
                console.log('$("#myTable")=',$("#myTable"));
                console.log('$("td")=',$("td"));
            });
        </script>
    </head>

    <body>
        <a href="#">Link1</a>
        <a href="#">Link2</a>
        <table id="myTable">
            <tr class="myRow"><td>td11</td><td>td12</td></tr>
            <tr class="myRow"><td>td21</td><td>td22</td></tr>
        </table>
    </body> 
</html>
69
user1032531

Je vais d’abord expliquer la différence entre NodeList et HTMLCollection.

Les deux interfaces sont collections de noeuds DOM. Ils diffèrent par les méthodes qu'ils fournissent et par le type de nœuds qu'ils peuvent contenir. Alors qu'une NodeList peut contenir n'importe quel type de nœud, une HTMLCollection est supposée contenir uniquement des nœuds d'élément.
Une HTMLCollection fournit les mêmes méthodes qu’un NodeList et en plus une méthode appelée namedItem.

Les collections sont toujours utilisées lorsque l'accès doit être fourni à plusieurs nœuds, par exemple. la plupart des méthodes de sélecteur (telles que getElementsByTagName) renvoient plusieurs noeuds ou obtiennent une référence à tous les enfants (element.childNodes).

Pour plus d'informations, consultez Spécification DOM4 - Collections .

Quelle est la différence entre document.getElementsByTagName("td") et $("td")?

getElementsByTagName est une méthode de l'interface DOM. Il accepte un nom de balise en entrée et retourne une HTMLCollection (voir spécification DOM4 ).

$("td") est probablement jQuery. Il accepte tous les sélecteurs CSS/jQuery valides et renvoie un objet jQuery.

La plus grande différence entre les collections DOM standard et les sélections jQuery réside dans le fait que les collections DOM sont typiquement actives (toutes les méthodes ne renvoient cependant pas de collection active), c'est-à-dire que toute modification apportée au DOM est reflétée dans les collections si elles sont affectées. Ils ressemblent à une vue sur l’arbre DOM, alors que les sélections jQuery sont des instantanés de l’arbre DOM au moment où la fonction a été appelée.

Pourquoi console.log affiche-t-il également le tableau des éléments DOM à côté d'eux, et ne sont-ils pas des objets et non un tableau?

les objets jQuery sont des objets array-like, c’est-à-dire qu’ils ont des propriétés numériques et une propriété length (gardez à l’esprit que les tableaux ne sont que des objets eux-mêmes). Les navigateurs ont tendance à afficher les tableaux et les objets de type tableau de manière particulière, comme [ ... , ... , ... ].

Qu'est-ce que les "NodeLists" insaisissables, et comment puis-je en choisir une?

Voir la première partie de ma réponse. Vous ne pouvez pas sélectionnerNodeLists, ils sont le résultat d'une sélection. 

Autant que je sache, il n’existe pas de moyen de créer NodeLists par programme (c’est-à-dire créer un vide et ajouter des nœuds plus tard), ils ne sont retournés que par certaines méthodes/propriétés du DOM.

92
Felix Kling

0. Quelle est la différence entre une HTMLCollection et une NodeList?

Voici quelques définitions pour vous.

Spécification DOM niveau 1 - Définitions d'objets divers :

Interface HTMLCollection

Une HTMLCollection est une liste de noeuds. Un nœud individuel peut être accédé par un index ordinal ou par le nom ou les attributs id du nœud. Remarque: les collections dans le DOM HTML sont supposées être actives, ce qui signifie qu'elles sont automatiquement mises à jour lorsque le document sous-jacent est modifié.

Spécification DOM niveau 3 - NodeList

Liste de nœuds d'interface

L'interface NodeList fournit l'abstraction d'une collection ordonnée de noeuds, sans définir ni contraindre la manière dont cette collection est implémentée. Les objets NodeList dans le DOM sont vivants.

Les éléments de la liste de noeuds sont accessibles via un index intégral, à partir de 0.

Ainsi, ils peuvent tous deux contenir des données en temps réel, ce qui signifie que le DOM sera mis à jour lorsque leurs valeurs le seront. Ils contiennent également un ensemble de fonctions différent.

Vous remarquerez si vous inspectez la console si vous exécutez vos scripts que l'élément DOM table contient à la fois un childNodesNodeList[2] et un childrenHTMLCollection[1]. Pourquoi sont-ils différents? Comme HTMLCollection ne peut contenir que des nœuds d’élément, NodeList contient également un nœud de texte.

enter image description here

1. Quelle est la différence entre document.getElementsByTagName("td") et $("td")?

document.getElementsByTagName("td") renvoie un tableau d'éléments DOM (une NodeList), $("td") est appelé un objet jQuery qui contient les éléments de document.getElementsByTagName("td") sur ses propriétés 0, 1, 2, etc. La différence principale est que l'objet jQuery est un peu plus lent à récupérer mais donne accès à toutes les fonctions pratiques de jQuery.

2. $("#myTable") et $("td") sont des objets (objets jQuery). Pourquoi console.log affiche-t-il également le tableau des éléments DOM à côté d'eux, et ne sont-ils pas des objets et non un tableau?

Ce sont des objets dont les propriétés 0, 1, 2, etc. sont définies sur les éléments DOM. Voici un exemple simple: de la façon dont cela fonctionne:

jsFiddle

    var a = {
        1: "first",
        2: "second"
    }
    alert(a[1]);

3. Qu'est-ce que les "NodeLists" insaisissables, et comment puis-je en choisir une?

Vous les avez récupérées dans votre code, getElementsByClassName et getElementsByTagName retournent tous deux NodeLists

NodeList

27
Daniel Imms

$("td") est un objet jQuery étendu et il a des méthodes jQuery, il retourne un objet jQuery contenant un tableau d'objets HTML document.getElementsByTagName("td") est une méthode js brute et renvoie NodeList. Voir cet article

2
karaxuna

Remarque additionnelle

Quelle est la différence entre une collection HTMLC et une liste de noeuds?

Un HTMLCollection contient uniquement des nœuds d'élément (tags) et un NodeList contient tous les nœuds.

Il existe quatre types de nœuds:

  1. noeud d'élément
  2. noeud d'attribut
  3. noeud de texte
  4. noeud de commentaire

nodeTypes

Les espaces blancs à l'intérieur des éléments sont considérés comme du texte et le texte comme des nœuds.

Considérer ce qui suit:

<ul id="myList">
  <!-- List items -->
  <li>List item 1</li> 
  <li>List item 2</li>
  <li>List item 3</li>
  <li>List item 4</li>
  <li>List item 5</li>
</ul>

Espace blanc: <ul id="myList"> <li>List item</li></ul>

Aucun espace: <ul id="myList"><li>List item</li></ul>

 Difference between HTMLCollection and a NodeList

2
Sun

Les objets NodeList sont des collections de nœuds, renvoyés par exemple par x. childNodes property ou document.querySelectorAll () method. Dans certains cas, NodeList est live, ce qui signifie que les modifications dans le DOM mettent automatiquement à jour la collection! Par exemple, Node.childNodes est en direct: 

var c = parent.childNodes; //assume c.length is 2
parent.appendChild(document.createElement('div'));
//now c.length is 3, despite the `c` variable is assigned before appendChild()!!
//so, do not cache the list's length in a loop.

Mais dans d'autres cas, NodeList est static, où toute modification dans le DOM n'affecte pas le contenu de la collection. querySelectorAll () retourne une liste de noeuds statique.

La HTMLCollection est une collection d'éléments live et orders (elle est automatiquement mise à jour lorsque le document sous-jacent est modifié). Cela peut être le résultat de propriétés telles que children ou de méthodes telles que document.getElementsByTagName () , et ne peut avoir que HTMLElement comme éléments. 

HTMLCollection expose également ses membres directement en tant que propriétés à la fois par nom et par index:

var f = document.forms; // this is an HTMLCollection
f[0] === f.item(0) === f.myForm //assume first form id is 'myForm'

HTMLElement n'est qu'un type de nœuds:

 Node << HTMLElement inheritance

Le nœud peut être plusieurs types . Les plus importants sont les suivants:

  • element (1): nœud d'élément tel que <p> ou <div>.
  • attribut (2): attribut d'un élément. Les attributs d'élément n'implémentent plus l'interface Node dans la spécification DOM4!
  • text (3): le texte réel de l'élément ou de l'attribut.
  • comment (8): un noeud de commentaire.
  • document (9): un noeud de document.

Donc, une grande différence est que HTMLCollection ne contient que HTMLElements mais NodeList contient également les commentaires, les textes d’espace (caractères de retour chariot, espaces ..), etc. Cochez-le comme dans l'extrait suivant:

function printList(x, title) {
  console.log("\r\nprinting "+title+" (length="+x.length+"):");
  for(var i=0; i<x.length; i++) {
    console.log("  "+i+":"+x[i]);
  }
}

var elems = document.body.children; //HTMLCollection
var nodes = document.body.childNodes; //NodeList

printList(elems, "children [HTMLCollection]");
printList(nodes, "childNodes [NodeList]");
<div>para 1</div><!-- MyComment -->
<div>para 2</div>

HTMLCollection et NodeList contiennent tous les deux la propriété length que vous pouvez utiliser pour loop sur leurs éléments. N'utilisez pas for ... in ou for each ... in pour énumérer les éléments de NodeLists, car ils énuméreront également sa longueur et ses propriétés, et provoqueront des erreurs si votre script suppose qu'il ne doit traiter que des objets element. En outre, pour..in n'est pas garanti de visiter les propriétés dans un ordre particulier.

for (var i = 0; i < myNodeList.length; i++) {
  var item = myNodeList[i];
}
0
S.Serpooshan