Jaka jest różnica między dziećmi i childNodes w JavaScript?


305

Znalazłem się w użyciu JavaScript i natknąłem się na childNodesi childrenwłaściwości. Zastanawiam się, jaka jest różnica między nimi. Czy też jeden jest lepszy od drugiego?

Odpowiedzi:


330

Zrozum, że .childrenjest to właściwość elementu . 1 Tylko elementy mają .children, a wszystkie te elementy potomne są typu elementu. 2)

Jednak .childNodesjest własnością węzła . .childNodesmoże zawierać dowolny węzeł. 3)

Konkretnym przykładem byłoby:

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

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

.childrenPrzez większość czasu chcesz używać, ponieważ generalnie nie chcesz zapętlać węzłów Tekst lub Komentarz podczas manipulacji DOM.

Jeśli chcesz manipulować węzłami tekstowymi, prawdopodobnie .textContentzamiast tego chcesz . 4


1. Z technicznego punktu widzenia jest to atrybut ParentNode , miksu zawartego w elemencie.
2. Wszystkie są elementami, ponieważ .childrenjest to kolekcja HTMLC , która może zawierać tylko elementy.
3. Podobnie .childNodesmoże pomieścić dowolny węzeł, ponieważ jest to lista NodeList .
4. Or .innerText. Zobacz różnice tutaj lub tutaj .


3
Tak, IE wydaje się mieć pewne problemy: quirksmode.org/dom/w3c_core.html#t71
Felix Kling

4
W rzeczywistości dzieci są własnością interfejsu nadrzędnego, a nie elementu. usonsci.wordpress.com/2014/09/30/html-children-vs-childnodes
zwycięzca

Wygląda na to, że iOS 8.3 (może inni?) Nie obsługuje .childrendokumentów XML : jsfiddle.net/fbwbjvch/1
Saebekassebil

4
Miał tylko problem z tym na Microsoft Edge z węzłami XML. Wygląda na to, że Microsoft Edge nie lubi dzieci. To dobrze, nie chciałbym, aby ta przeglądarka się odtwarzała.
Dan-Nolan

1
Naturalna kontynuacja „elementu vs. węzła”: stackoverflow.com/questions/132564/…
user1454265

23

Element.childrenzwraca tylko elementy potomne elementu , a Node.childNodeszwraca wszystkie elementy potomne węzła . Zauważ, że elementy są węzłami, więc oba są dostępne na elementach.

Wierzę, że childNodesjest bardziej niezawodny. Na przykład MDC (link powyżej) zauważa, że ​​IE ma childrenrację tylko w IE 9. childNodeszapewnia mniej miejsca na błędy dla implementatorów przeglądarki.


2
Cholera, gdyby tylko to działało na IE 6-8, byłoby spełnieniem marzeń.
Ry-

3
@minitech to działa (dla pewnej wartości pracy). Najwyraźniej .childrennie odfiltrowuje węzłów komentarzy, ale odfiltrowuje węzły tekstowe.
Raynos

2
@Raynos: Dokładnie - to samo z .getElementsByTagName('*'). Czasami IE może być tak denerwujące ...
Ry-

Istnieją implementacje shim / polyfill childrentego wsparcia IE.
wrlee

7

Dobre odpowiedzi do tej pory, chcę tylko dodać, że można sprawdzić typ węzła za pomocą nodeType:

yourElement.nodeType

To da ci liczbę całkowitą: (wzięte stąd )

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

Zauważ, że według Mozilli :

Następujące stałe są przestarzałe i nie powinny być już używane: Node.ATTRIBUTE_NODE, Node.ENTITY_REFERENCE_NODE, Node.ENTITY_NODE, Node.NOTATION_NODE


0

Wybierz jeden zależy od metody, której szukasz !?

Pójdę z ParentNode.children :

Ponieważ zapewnia namedItemmetodę, która pozwala mi bezpośrednio uzyskać jeden z elementów potomnych bez zapętlania wszystkich dzieci lub unikania używania getElementByIditp.

na przykład

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

Pójdę z Node.childNodes :

Ponieważ zapewnia forEachmetodę, gdy pracuję z window.IntersectionObserver np

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

W Chrome 83

Node.childNodes zapewnia entries, forEach, item, keys, lengthivalues

ParentNode.children zapewnia item, lengthinamedItem

Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.