ความแตกต่างระหว่างเด็กและโหนดเด็กใน 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เพราะโดยทั่วไปแล้วคุณไม่ต้องการวนซ้ำโหนดข้อความหรือข้อคิดเห็นในการจัดการ DOM ของคุณ

หากคุณต้องการจัดการกับโหนดข้อความคุณอาจต้องการ.textContentแทน 4


1. ในทางเทคนิคมันเป็นคุณสมบัติของParentNodeซึ่งเป็นมิกซ์อินที่รวมอยู่ในองค์ประกอบ
2. เป็นองค์ประกอบทั้งหมดเพราะ.childrenเป็นHTMLCollectionซึ่งสามารถมีองค์ประกอบได้เท่านั้น
3. ในทำนองเดียวกัน.childNodesสามารถถือโหนดใด ๆ เพราะมันเป็นNodeList
4. .innerTextหรือ เห็นความแตกต่างที่นี่หรือที่นี่


3
ใช่ IE ดูเหมือนจะมีปัญหา: quirksmode.org/dom/w3c_core.html#t71
Felix Kling

4
ที่จริงแล้ว children คือคุณสมบัติของอินเตอร์เฟส parentnode ไม่ใช่องค์ประกอบ usonsci.wordpress.com/2014/09/30/html-children-vs-childnodes
ผู้ชนะ

ดูเหมือนว่า iOS 8.3 (อาจจะเป็นคนอื่น) ไม่รองรับ.childrenเอกสาร XML : jsfiddle.net/fbwbjvch/1
Saebekassebil

4
มีปัญหาในเรื่องนี้กับ Microsoft Edge ที่มีโหนด XML เท่านั้น ดูเหมือนว่า Microsoft Edge จะไม่ชอบเด็ก ๆ ดีฉันไม่ต้องการให้เบราว์เซอร์นั้นทำซ้ำ
Dan-Nolan

1
การติดตามอย่างเป็นธรรมชาติของ "องค์ประกอบ vs. โหนด": stackoverflow.com/questions/132564/ …
1454265

23

Element.childrenส่งคืนอิลิเมนต์ลูกเท่านั้นในขณะที่Node.childNodesส่งคืนโหนดลูกทั้งหมด โปรดทราบว่าองค์ประกอบนั้นเป็นโหนดดังนั้นทั้งคู่จึงมีอยู่ในองค์ประกอบ

ฉันเชื่อว่าchildNodesน่าเชื่อถือมากขึ้น ตัวอย่างเช่น MDC (เชื่อมโยงด้านบน) ตั้งข้อสังเกตว่า IE มีchildrenสิทธิ์ใน IE 9 เท่านั้น childNodesให้พื้นที่น้อยกว่าสำหรับข้อผิดพลาดโดยผู้ใช้เบราว์เซอร์


2
Darn ถ้าเพียงแค่ทำงานใน IE 6-8 มันจะเป็นความฝันที่เป็นจริง
Ry-

3
@minitech ใช้งานได้ (สำหรับบางค่าของงาน) เห็นได้ชัด.childrenว่าไม่ได้กรองโหนดความคิดเห็น แต่จะกรองโหนดข้อความออก
Raynos

2
@Raynos: เผง - .getElementsByTagName('*')เช่นเดียวกันกับ บางครั้ง IE อาจสร้างความรำคาญให้กับตัวเอง ...
Ry-

มีการใช้งาน shim / polyfill ของchildrenIE ที่สนับสนุน
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

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.