web-dev-qa-db-ger.com

Unterschied zwischen HTMLCollection, NodeLists und Arrays von Objekten

Ich war immer verwirrt zwischen HTMLC-Sammlungen, Objekten und Arrays, wenn es um DOM geht. Zum Beispiel...

  1. Was ist der Unterschied zwischen document.getElementsByTagName("td") und $("td")?
  2. $("#myTable") und $("td") sind Objekte (jQuery-Objekte). Warum zeigt Console.log auch das Array von DOM-Elementen neben ihnen an, und sind es keine Objekte und kein Array?
  3. Worum geht es bei den schwer fassbaren "NodeLists" und wie wähle ich eine aus?

Bitte geben Sie auch eine Interpretation des unten stehenden Skripts an.

Vielen Dank

[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

Zuerst werde ich den Unterschied zwischen NodeList und HTMLCollection erklären.

Beide Schnittstellen sind collection von DOM-Knoten. Sie unterscheiden sich in den von ihnen bereitgestellten Methoden und in der Art der Knoten, die sie enthalten können. Während ein NodeList einen beliebigen Knotentyp enthalten kann, soll ein HTMLCollection nur Elementknoten enthalten.
Ein HTMLCollection bietet die gleichen Methoden wie ein NodeList und zusätzlich eine Methode mit dem Namen namedItem.

Sammlungen werden immer dann verwendet, wenn Zugriff auf mehrere Knoten gewährt werden muss, z. Die meisten Auswahlmethoden (wie getElementsByTagName) geben mehrere Knoten zurück oder erhalten einen Verweis auf alle untergeordneten Elemente (element.childNodes).

Weitere Informationen finden Sie unter DOM4-Spezifikation - Sammlungen .

Was ist der Unterschied zwischen document.getElementsByTagName("td") und $("td")?

getElementsByTagName ist die Methode der DOM-Schnittstelle. Es akzeptiert einen Tag-Namen als Eingabe und gibt ein HTMLCollection zurück (siehe DOM4-Spezifikation ).

$("td") ist vermutlich jQuery. Es akzeptiert alle gültigen CSS/jQuery-Selektoren und gibt ein jQuery-Objekt zurück.

Die größten Unterschiede zwischen Standard-DOM-Sammlungen und jQuery-Auswahlen bestehen darin, dass DOM-Sammlungen typischerweise live sind (nicht alle Methoden geben jedoch eine Live-Sammlung zurück), d. Sie sind wie ein view im DOM-Baum, während jQuery-Auswahl Momentaufnahmen des DOM-Baums in dem Moment ist, in dem die Funktion aufgerufen wurde.

Warum zeigt Console.log auch das Array von DOM-Elementen neben ihnen an, und sind es keine Objekte und kein Array?

jQuery-Objekte sind array-like - Objekte, d. h. sie haben numerische Eigenschaften und eine length-Eigenschaft (beachten Sie, dass Arrays nur Objekte selbst sind). Browser neigen dazu, Arrays und Array-ähnliche Objekte auf besondere Weise anzuzeigen, wie [ ... , ... , ... ].

Worum geht es bei den schwer fassbaren "NodeLists" und wie wähle ich eine aus?

Siehe den ersten Teil meiner Antwort. Sie können nicht NodeLists auswählen, sie sind das Ergebnis einer Auswahl. 

Soweit ich weiß, gibt es nicht einmal eine Möglichkeit, NodeLists programmgesteuert zu erstellen (d. H. Eine leere zu erstellen und später Knoten hinzuzufügen).

92
Felix Kling

0. Was ist der Unterschied zwischen einer HTMLCollection und einer NodeList?

Hier sind einige Definitionen für Sie.

DOM Level 1 Spec - Verschiedene Objektdefinitionen :

Schnittstelle HTMLCollection

Eine HTMLCollection ist eine Liste von Knoten. Auf einen einzelnen Knoten kann entweder über den Ordinalindex oder die Namen- oder ID-Attribute des Knotens zugegriffen werden. Hinweis: Sammlungen im HTML-DOM gelten als live, was bedeutet, dass sie automatisch aktualisiert werden, wenn das zugrunde liegende Dokument geändert wird.

DOM Level 3 Spec - Knotenliste

Interface NodeList

Die NodeList-Schnittstelle bietet die Abstraktion einer geordneten Auflistung von Knoten, ohne zu definieren oder zu beschränken, wie diese Auflistung implementiert wird. NodeList-Objekte im DOM sind live.

Die Elemente in der NodeList sind über einen integrierten Index ab 0 verfügbar.

Sie können also beide Live-Daten enthalten, was bedeutet, dass das DOM aktualisiert wird, wenn seine Werte dies tun. Sie enthalten auch andere Funktionen.

Wenn Sie die Konsole überprüfen, werden Sie feststellen, dass das DOM-Element table sowohl eine childNodesNodeList[2] als auch eine childrenHTMLCollection[1] enthält. Warum unterscheiden sie sich? Da HTMLCollection nur Elementknoten enthalten kann, enthält NodeList auch einen Textknoten.

enter image description here

1. Was ist der Unterschied zwischen document.getElementsByTagName("td") und $("td")?

document.getElementsByTagName("td") gibt ein Array von DOM-Elementen (eine NodeList) zurück. $("td") wird als jQuery-Objekt bezeichnet, dessen Elemente document.getElementsByTagName("td") die Eigenschaften 0, 1, 2 usw. enthalten gibt aber Zugriff auf alle praktischen jQuery-Funktionen.

2. $("#myTable") und $("td") sind Objekte (jQuery-Objekte). Warum zeigt console.log auch das Array von DOM-Elementen neben sich, und sind es keine Objekte und kein Array?

Sie sind Objekte, deren Eigenschaften 0, 1, 2 usw. auf die DOM-Elemente festgelegt sind. Hier ein einfaches Beispiel: Wie es funktioniert:

jsFiddle

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

3. Worum geht es bei den schwer fassbaren "NodeLists" und wie wähle ich eine aus?

Sie haben sie in Ihrem Code abgerufen, getElementsByClassName und getElementsByTagName geben beide NodeLists zurück

NodeList

27
Daniel Imms

$("td") ist ein erweitertes jQuery-Objekt, das über jQuery-Methoden verfügt. Es gibt ein Jquery-Objekt zurück, das ein Array von HTML-Objekten enthält. document.getElementsByTagName("td") ist eine unformatierte js-Methode und gibt NodeList zurück. Siehe diesen Artikel

2
karaxuna

Zusätzliche Anmerkung

Was ist der Unterschied zwischen einer HTMLCollection und einer NodeList?

Eine HTMLCollection enthält nur Elementknoten (tags) und eine NodeList enthält alle node.

Es gibt vier Knotentypen:

  1. elementknoten
  2. attributknoten
  3. textknoten
  4. kommentarknoten

nodeTypes

Leerzeichen innerhalb von Elementen werden als Text und Text als Knoten betrachtet.

Folgendes berücksichtigen:

<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>

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

Kein Leerzeichen: <ul id="myList"><li>List item</li></ul>

 Difference between HTMLCollection and a NodeList

2
Sun

Die NodeList - Objekte sind Sammlungen von Nodes, die beispielsweise von der Methode x. childNodes property oder document.querySelectorAll () zurückgegeben werden. In einigen Fällen ist die NodeList live, was bedeutet, dass Änderungen im DOM die Sammlung automatisch aktualisieren! Zum Beispiel ist Node.childNodes live: 

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.

In einigen anderen Fällen ist die NodeList static, wobei Änderungen im DOM den Inhalt der Auflistung nicht beeinflussen. querySelectorAll () gibt eine statische NodeList zurück.

Die HTMLCollection ist eine live und geordnete -Sammlung von Elementen (sie wird automatisch aktualisiert, wenn das zugrunde liegende Dokument geändert wird). Dies kann das Ergebnis von Eigenschaften wie children oder Methoden wie document.getElementsByTagName () sein, und könnte nur HTMLElement's als Elemente enthalten. 

HTMLCollection macht ihre Mitglieder auch direkt nach Name und Index als Eigenschaften verfügbar:

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

Das HTMLElement ist nur eine Art von Knoten:

 Node << HTMLElement inheritance

Der Knoten kann verschiedene Typen sein. Die wichtigsten sind wie folgt:

  • element (1): Ein Elementknoten wie <p> oder <div>.
  • attribut (2): Ein Attribut eines Elements. Die Elementattribute implementieren die Node-Schnittstelle nicht mehr in der DOM4-Spezifikation!
  • text (3): Der tatsächliche Text eines Elements oder Attributs.
  • kommentar (8): Ein Kommentarknoten.
  • dokument (9): Ein Dokumentenknoten.

Ein großer Unterschied besteht jedoch darin, dass HTMLCollection nur HTMLElements enthält, NodeList jedoch auch die Kommentare, Leerzeichen (Wagenrücklaufzeichen, Leerzeichen usw.) usw. enthält. Überprüfen Sie es wie in folgendem Snippet:

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>

Sowohl HTMLCollection als auch NodeList enthalten die length - Eigenschaft, die Sie verwenden können, um loop für ihre Elemente zu verwenden. Verwenden Sie nicht für ... in oder for each ... in, um die Elemente in NodeLists aufzulisten, da diese auch ihre Längen- und Elementeigenschaften auflisten und Fehler verursachen, wenn Ihr Skript davon ausgeht, dass es nur mit Elementobjekten zu tun hat. Für..in ist es nicht garantiert, die Objekte in einer bestimmten Reihenfolge zu besuchen.

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