Ich habe mich gefragt, ob JavaScript eine Vielzahl von Methoden bietet, um das erste untergeordnete Element aus einem Element abzurufen. Aber welches ist das beste? Mit "am besten" meine ich: am meisten browserübergreifend kompatibel, am schnellsten, am umfassendsten und vorhersehbarsten, wenn es um Verhalten geht. Eine Liste der Methoden / Eigenschaften, die ich als Aliase verwende:
var elem = document.getElementById('container');
var child = elem.children[0];
var child = elem.firstElementChild; // == children[0]
Dies funktioniert in beiden Fällen:
var child = elem.childNodes[0]; // or childNodes[1], see below
Dies ist bei Formularen oder <div>
Iterationen der Fall . Wenn ich auf Textelemente stoßen könnte:
var child = elem.childNodes; // treat as NodeList
var child = elem.firstChild;
Soweit ich firstChild
das beurteilen kann, verwendet die NodeList von childNodes
und firstElementChild
verwendet children
. Ich stütze diese Annahme auf die MDN-Referenz:
childNode
ist eine Referenz auf das erste untergeordnete Element des Elementknotens odernull
wenn es keines gibt.
Ich vermute, dass in Bezug auf die Geschwindigkeit der Unterschied, wenn überhaupt, so gut wie nichts sein wird, da er firstElementChild
effektiv eine Referenz children[0]
ist und das children
Objekt ohnehin bereits im Speicher ist.
Was mich wirft, ist das childNodes
Objekt. Ich habe es verwendet, um ein Formular in einem Tabellenelement zu betrachten. Während children
alle Formularelemente aufgelistet werden, childNodes
scheint es auch Leerzeichen aus dem HTML-Code zu geben:
console.log(elem.childNodes[0]);
console.log(elem.firstChild);
Beide protokollieren <TextNode textContent="\n ">
console.log(elem.childNodes[1]);
console.log(elem.children[0]);
console.log(elem.firstElementChild);
Alle protokollieren <input type="text"
… >
. Woher? Ich würde verstehen, dass ein Objekt es mir ermöglichen würde, mit dem „rohen“ HTML-Code zu arbeiten, während das andere beim DOM bleibt, aber das childNodes
Element scheint auf beiden Ebenen zu funktionieren.
Um auf meine ursprüngliche Frage zurückzukommen, würde ich raten: Wenn ich das umfassendste Objekt haben möchte, childNodes
ist dies der richtige Weg, aber aufgrund seiner Vollständigkeit ist es möglicherweise nicht das vorhersehbarste, wenn es das gewünschte Element zurückgibt. zu jedem Zeitpunkt erwarten. Die browserübergreifende Unterstützung könnte sich in diesem Fall ebenfalls als Herausforderung erweisen, obwohl ich mich irren könnte.
Könnte jemand die Unterscheidung zwischen den vorliegenden Objekten klarstellen? Wenn es einen Geschwindigkeitsunterschied gibt, wie vernachlässigbar er auch sein mag, würde ich gerne wissen. Wenn ich das alles falsch sehe, kannst du mich gerne erziehen.
PS: Bitte, bitte, ich mag JavaScript, also ja, ich möchte mich mit so etwas befassen. Antworten wie „jQuery kümmert sich für Sie darum“ sind nicht das, wonach ich suche, daher neinjquery Etikett.
quelle
Antworten:
Klingt so, als würden Sie es überdenken. Sie haben den Unterschied zwischen
childNodes
und beobachtetchildren
, derchildNodes
alle Knoten enthält, einschließlich Textknoten, die vollständig aus Leerzeichen bestehen, währendchildren
es sich nur um eine Sammlung der untergeordneten Knoten handelt, die Elemente sind. Das ist wirklich alles.An beiden Sammlungen ist nichts Unvorhersehbares, obwohl einige Punkte zu beachten sind:
childNodes
während andere Browser dies tunchildren
während andere Browser nur Elemente enthaltenchildren
,firstElementChild
Und Freunde sind nur Komfort, eine gefilterte Ansicht des DOM beschränkt auf nur Elemente präsentieren.quelle
<td\n\t>content</td>
. Wie bei XML, um zu vermeiden, dass überschüssiges Leerzeichen als Teil der Daten (oder in diesem Fall als DOM) betrachtet wird. Warum sollten Leerzeichen in einem Tag in das DOM aufgenommen werden?children
IE 4 über ein Jahrzehnt entstanden ist, bevor es zum Standard wurde oder von anderen Browsern übernommen wurde, könnte man argumentieren, dass IE <= 8 korrekt und andere Browser falsch sind.firstElementChild ist möglicherweise nicht in IE <9 verfügbar (nur firstChild)
on IE <9 firstChild ist das firstElementChild, da MS DOM (IE <9) keine leeren Textknoten speichert. Wenn Sie dies jedoch in anderen Browsern tun, werden leere Textknoten zurückgegeben ...
meine Lösung
child=(elem.firstElementChild||elem.firstChild)
Dies gibt das erste Kind sogar auf IE <9
quelle
elem.firstChild
es sich nicht um einen Elementknoten handelt, sind die Ergebnisse in alten IEs unterschiedlich, daelem.firstElementChild
es sich immer um einen Elementknoten handelt.firstElementChild
ist auch in Nicht-IE-Browsern nicht unbedingt sicher: Firefox unterstützt es erst in Version 3.5.Die Cross - Browser - Art und Weise zu tun ist , zu verwenden ,
childNodes
zu erhaltenNodeList
, dann einen Array aller Knoten mit machennodeType
ELEMENT_NODE .http://jsfiddle.net/s4kxnahu/
Dies ist besonders einfach, wenn Sie eine Dienstprogrammbibliothek wie lodash verwenden :
Zukunft:
Sie können
querySelectorAll
in Kombination mit einer:scope
Pseudoklasse verwenden (entspricht dem Element, das der Referenzpunkt des Selektors ist):Zum Zeitpunkt des Schreibens
:scope
wird dies in Chrome, Firefox und Safari unterstützt.quelle
Um die anderen Antworten zu ergänzen, gibt es hier immer noch bemerkenswerte Unterschiede, insbesondere beim Umgang mit
<svg>
Elementen.Ich habe beides benutzt
.childNodes
und.children
es vorgezogen, mit demHTMLCollection
vom.children
Getter gelieferten zu arbeiten .Heute stieß ich jedoch auf Probleme mit IE / Edge-Fehlern bei der Verwendung
.children
auf einem<svg>
. Während.children
es im IE für grundlegende HTML-Elemente unterstützt wird, wird es für Dokumente / Dokumentfragmente oder SVG-Elemente nicht unterstützt .Für mich war es möglich, einfach die benötigten Elemente über zu erfassen,
.childNodes[n]
da ich keine überflüssigen Textknoten habe, über die ich mir Sorgen machen muss. Möglicherweise können Sie dasselbe tun, aber wie oben an anderer Stelle erwähnt, vergessen Sie nicht, dass Sie möglicherweise auf unerwartete Elemente stoßen..children
Ich hoffe, dies ist hilfreich für jemanden, der sich am Kopf kratzt und versucht herauszufinden, warum es an anderer Stelle in seinem js im modernen IE funktioniert und bei Dokumenten- oder SVG-Elementen fehlschlägt.quelle
Hey Leute, lasst euch nicht vom Leerraum täuschen. Testen Sie dies einfach in einem Konsolenbrowser. Verwenden Sie natives Javascript. Hier ist ein Beispiel mit zwei 'ul'-Mengen mit derselben Klasse. Sie müssen Ihre 'ul'-Liste nicht in einer Zeile haben, um Leerzeichen zu vermeiden. Verwenden Sie einfach Ihre Array-Anzahl, um über Leerzeichen zu springen.
Wie um Leerraum zu bekommen ,
querySelector()
dannchildNodes[]
Geige Link js: https://jsfiddle.net/aparadise/56njekdo/quelle
document.querySelector
wurde damals nicht gut unterstützt. b) Die Frage ist im Grunde, was die Unterschiede zwischenchildren
undchildNodes
intern sind , was zuverlässiger ist, wenn man sich voreinander entscheidet. und c) Da, wie in der Frage demonstraded:childNodes
nicht enthalten Leerzeichen Knoten,children
nicht ...