Qual è la differenza tra children e childNodes in JavaScript?


305

Mi sono trovato ad usare JavaScript e mi sono imbattuto in childNodese childrenproprietà. Mi chiedo quale sia la differenza tra loro. Anche uno è preferito all'altro?

Risposte:


330

Comprendi che .childrenè una proprietà di un elemento . 1 Solo gli elementi hanno .children, e questi figli sono tutti di tipo Element. 2

Tuttavia, .childNodesè una proprietà di Node . .childNodespuò contenere qualsiasi nodo. 3

Un esempio concreto sarebbe:

let el = document.createElement("div");
el.textContent = "foo";

el.childNodes.length === 1; // Contains a Text node child.
el.children.length === 0;   // No Element children.

Il più delle volte, vuoi usarlo .childrenperché generalmente non vuoi passare in rassegna i nodi di testo o commento nella tua manipolazione DOM.

Se vuoi manipolare i nodi di testo, probabilmente vorrai .textContentinvece. 4


1. Tecnicamente, è un attributo di ParentNode , un mixin incluso da Element.
2. Sono tutti elementi perché .childrenè un HTMLCollection , che può contenere solo elementi.
3. Allo stesso modo, .childNodespuò contenere qualsiasi nodo perché è un NodeList .
4. Or .innerText. Vedi le differenze qui o qui .


3
Sì, sembra che IE abbia dei problemi: quirksmode.org/dom/w3c_core.html#t71
Felix Kling,

4
In realtà, children è una proprietà dell'interfaccia parentnode, non un elemento. usonsci.wordpress.com/2014/09/30/html-children-vs-childnodes
victor

Sembra che iOS 8.3 (forse altri?) Non supporti .childreni documenti XML : jsfiddle.net/fbwbjvch/1
Saebekassebil,

4
Ho avuto problemi solo con questo su Microsoft Edge con nodi XML. Sembra che a Microsoft Edge non piacciano i bambini. Bene, non vorrei che quel browser si riproducesse.
Dan-Nolan,

1
Follow-up naturale di "elemento vs. nodo": stackoverflow.com/questions/132564/...
user1454265

23

Element.childrenrestituisce solo elementi figlio, mentre Node.childNodesrestituisce tutti i nodi figlio. Si noti che gli elementi sono nodi, quindi entrambi sono disponibili sugli elementi.

Credo childNodessia più affidabile. Ad esempio, MDC (collegato sopra) osserva che IE ha funzionato childrencorrettamente solo in IE 9. childNodesoffre meno spazio agli errori dagli implementatori del browser.


2
Accidenti, se solo funzionasse su Internet Explorer 6-8, sarebbe un sogno diventato realtà.
Ry-

3
@minitech funziona (per un certo valore del lavoro). Apparentemente .childrennon filtra i nodi di commento, ma filtra i nodi di testo.
Raynos,

2
@Raynos: esattamente - lo stesso con .getElementsByTagName('*'). IE a volte può essere così fastidioso ...
Ry-

Esistono implementazioni shim / polyfill di childrentale supporto IE.
wrlee,

7

Buone risposte finora, voglio solo aggiungere che è possibile verificare il tipo di nodo usando nodeType:

yourElement.nodeType

Questo ti darà un numero intero: (preso da qui )

| Value |             Constant             |                          Description                          |  |
|-------|----------------------------------|---------------------------------------------------------------|--|
|    1  | Node.ELEMENT_NODE                | An Element node such as <p> or <div>.                         |  |
|    2  | Node.ATTRIBUTE_NODE              | An Attribute of an Element. The element attributes            |  |
|       |                                  | are no longer implementing the Node interface in              |  |
|       |                                  | DOM4 specification.                                           |  |
|    3  | Node.TEXT_NODE                   | The actual Text of Element or Attr.                           |  |
|    4  | Node.CDATA_SECTION_NODE          | A CDATASection.                                               |  |
|    5  | Node.ENTITY_REFERENCE_NODE       | An XML Entity Reference node. Removed in DOM4 specification.  |  |
|    6  | Node.ENTITY_NODE                 | An XML <!ENTITY ...> node. Removed in DOM4 specification.     |  |
|    7  | Node.PROCESSING_INSTRUCTION_NODE | A ProcessingInstruction of an XML document                    |  |
|       |                                  | such as <?xml-stylesheet ... ?> declaration.                  |  |
|    8  | Node.COMMENT_NODE                | A Comment node.                                               |  |
|    9  | Node.DOCUMENT_NODE               | A Document node.                                              |  |
|   10  | Node.DOCUMENT_TYPE_NODE          | A DocumentType node e.g. <!DOCTYPE html> for HTML5 documents. |  |
|   11  | Node.DOCUMENT_FRAGMENT_NODE      | A DocumentFragment node.                                      |  |
|   12  | Node.NOTATION_NODE               | An XML <!NOTATION ...> node. Removed in DOM4 specification.   |  |

Si noti che secondo Mozilla :

Le seguenti costanti sono state deprecate e non devono più essere utilizzate: Node.ATTRIBUTE_NODE, Node.ENTITY_REFERENCE_NODE, Node.ENTITY_NODE, Node.NOTATION_NODE


0

Scegline uno dipende dal metodo che stai cercando !?

Andrò con ParentNode.children :

Poiché fornisce un namedItemmetodo che mi consente di ottenere direttamente uno degli elementi figlio senza scorrere tutti i bambini o evitare di usarlogetElementById ecc.

per esempio

ParentNode.children.namedItem('ChildElement-ID'); // JS
ref.current.children.namedItem('ChildElement-ID'); // React
this.$refs.ref.children.namedItem('ChildElement-ID'); // Vue

Andrò con Node.childNodes :

Come fornisce forEachmetodo quando lavoro con window.IntersectionObserver es

nodeList.forEach((node) => { observer.observe(node) })
// IE11 does not support forEach on nodeList, but easy to be polyfilled.

Su Chrome 83

Node.childNodes fornisce entries, forEach, item, keys, lengthevalues

ParentNode.children fornisce item, lengthenamedItem

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.