В чем разница между дочерними и дочерними узлами в JavaScript?


305

Я нашел себя , используя JavaScript и я натыкался childNodesи childrenсвойства. Мне интересно, в чем разница между ними. Также один предпочтительнее другого?

Ответы:


330

Поймите, что .childrenэто свойство элемента . 1 Только элементы имеют .children, и все эти потомки имеют тип элемента. 2

Тем не менее, .childNodesявляется собственностью узла . .childNodesможет содержать любой узел. 3

Конкретный пример будет:

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

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

Большую часть времени вы хотите использовать, .childrenпотому что обычно вы не хотите зацикливаться на узлах Text или Comment при манипуляциях с DOM.

Если вы хотите манипулировать текстовыми узлами, вы, вероятно, хотите .textContentвместо этого. 4


1. Технически, это атрибут ParentNode , миксина , включенного в Element.
2. Все они являются элементами, потому что .childrenэто HTMLCollection , которая может содержать только элементы.
3. Аналогично, .childNodesможет содержать любой узел, потому что это NodeList .
4. Или .innerText. Смотрите различия здесь или здесь .


3
Да, у IE, похоже, есть некоторые проблемы: quirksmode.org/dom/w3c_core.html#t71
Феликс Клинг

4
На самом деле children - это свойство интерфейса parentnode, а не элемента. usonsci.wordpress.com/2014/09/30/html-children-vs-childnodes
победитель

Кажется, iOS 8.3 (может быть, другие?) Не поддерживает .childrenXML-документы : jsfiddle.net/fbwbjvch/1
Saebekassebil

4
Были проблемы только с Microsoft Edge с узлами XML. Похоже, Microsoft Edge не любит детей. Это хорошо, я бы не хотел, чтобы этот браузер воспроизводил.
Дан-Нолан

1
Естественное продолжение «элемент против узла»: stackoverflow.com/questions/132564/…
user1454265

23

Element.childrenвозвращает только дочерние элементы , а Node.childNodesвозвращает все дочерние узлы . Обратите внимание, что элементы являются узлами, поэтому оба элемента доступны для элементов.

Я считаю childNodesболее надежным. Например, MDC (ссылка выше) отмечает, что IE получил childrenправа только в IE 9. childNodesПредоставляет меньше возможностей для ошибок разработчикам браузеров.


2
Черт возьми, если бы только это работало на IE 6-8, это была бы мечта.
Ry-

3
@minitech это работает (для некоторой ценности работы). Очевидно .children, не отфильтровывает узлы комментариев, но отфильтровывает текстовые узлы.
Рейнос

2
@Raynos: Точно - то же самое с .getElementsByTagName('*'). IE может иногда быть таким раздражающим ...
Ry-

Существуют реализации shim / polyfill, childrenкоторые поддерживают IE.
wrlee

7

Хорошие ответы до сих пор, я хочу только добавить, что вы можете проверить тип узла, используя nodeType:

yourElement.nodeType

Это даст вам целое число: (взято отсюда )

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

Обратите внимание, что в соответствии с Mozilla :

Следующие константы устарели и больше не должны использоваться: Node.ATTRIBUTE_NODE, Node.ENTITY_REFERENCE_NODE, Node.ENTITY_NODE, Node.NOTATION_NODE


0

Выберите один зависит от метода, который вы ищете !?

Я пойду с ParentNode.children :

Так как он предоставляет namedItemметод, который позволяет мне напрямую получить один из дочерних элементов, не просматривая все дочерние элементы или избегая использования getElementByIdи т. Д.

например

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

Я пойду с Node.childNodes :

Как это обеспечивает forEachметод, когда я работаю с, window.IntersectionObserver например,

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

На Chrome 83

Node.childNodes обеспечивает entries, forEach, item, keys, lengthиvalues

ParentNode.children обеспечивает item, lengthиnamedItem

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.