Sự khác biệt giữa trẻ em và childNodes trong JavaScript là gì?


305

Tôi đã tìm thấy chính mình bằng cách sử dụng JavaScript và tôi đã chạy qua childNodeschildrencác thuộc tính. Tôi tự hỏi sự khác biệt giữa chúng là gì. Cũng là một trong những ưa thích khác?

Câu trả lời:


330

Hiểu rằng đó .childrenlà một tài sản của một yếu tố . 1 Chỉ các yếu tố mới có .children, và những đứa trẻ này đều thuộc loại Element. 2

Tuy nhiên, .childNodeslà một tài sản của Node . .childNodescó thể chứa bất kỳ nút nào. 3

Một ví dụ cụ thể sẽ là:

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

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

Hầu hết thời gian, bạn muốn sử dụng .childrenvì nhìn chung bạn không muốn lặp qua các nút Văn bản hoặc Nhận xét trong thao tác DOM của mình.

Nếu bạn muốn thao tác các nút Văn bản, có lẽ bạn muốn .textContentthay thế. 4


1. Về mặt kỹ thuật, nó là một thuộc tính của ParentNode , một mixin được bao gồm bởi Element.
2. Chúng đều là các phần tử vì .childrenHTMLCollection , chỉ có thể chứa các phần tử.
3. Tương tự, .childNodescó thể giữ bất kỳ nút nào vì nó là NodeList .
4. Hoặc .innerText. Xem sự khác biệt ở đây hoặc ở đây .


3
Vâng, IE dường như có một số vấn đề: quirksmode.org/dom/w3c_core.html#t71
Felix Kling

4
Trên thực tế, trẻ em là một thuộc tính của giao diện cha mẹ, không phải là phần tử. usonsci.wordpress.com/2014/09/30/html-children-vs-childnodes
người chiến thắng

Có vẻ như iOS 8.3 (có thể là những người khác?) Không hỗ trợ .childrentrên các tài liệu XML : jsfiddle.net/fbwbjvch/1
Saebekassebil

4
Chỉ gặp sự cố với điều này trên Microsoft Edge với các nút XML. Có vẻ như Microsoft Edge không thích trẻ con. Điều đó tốt, tôi sẽ không muốn trình duyệt đó sao chép.
Dan-Nolan

1
Theo dõi tự nhiên của "phần tử so với nút": stackoverflow.com/questions/132564/NH
user1454265

23

Element.childrenchỉ trả về phần tử con, trong khi Node.childNodestrả về tất cả các nút con. Lưu ý rằng các phần tử là các nút, vì vậy cả hai đều có sẵn trên các phần tử.

Tôi tin childNodeslà đáng tin cậy hơn. Ví dụ, MDC (được liên kết ở trên) lưu ý rằng IE chỉ có childrenquyền trong IE 9. childNodescung cấp ít lỗi hơn cho những người triển khai trình duyệt.


2
Darn, nếu chỉ điều này hoạt động trên IE 6-8, nó sẽ là một giấc mơ trở thành sự thật.
Ry-

3
@minitech nó hoạt động (đối với một số giá trị của công việc). Rõ ràng .childrenkhông lọc ra các nút bình luận, nhưng nó lọc ra các nút văn bản.
Raynos

2
@Raynos: Chính xác - giống với .getElementsByTagName('*'). IE đôi khi có thể rất khó chịu ...
Ry-

Có các triển khai shim / polyfill của childrenIE hỗ trợ đó.
quằn quại

7

Câu trả lời tốt cho đến nay, tôi chỉ muốn thêm rằng bạn có thể kiểm tra loại nút bằng cách sử dụng nodeType:

yourElement.nodeType

Điều này sẽ cung cấp cho bạn một số nguyên: (lấy từ đây )

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

Lưu ý rằng theo Mozilla :

Các hằng số sau đây không được dùng nữa và không nên sử dụng nữa: Node.ATTRIBUTE_NODE, Node.ENTITY_REFERENCE_NODE, Node.ENTITY_NODE, Node.NOTATION_NODE


0

Chọn một tùy thuộc vào phương pháp bạn đang tìm kiếm!?

Tôi sẽ đi với ParentNode.children :

Vì nó cung cấp namedItem phương thức cho phép tôi trực tiếp lấy một trong các phần tử con mà không lặp qua tất cả các phần tử con hoặc tránh sử dụng, getElementByIdv.v.

ví dụ

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

Tôi sẽ đi với Node.childNodes :

Vì nó cung cấp forEachphương thức khi tôi làm việc với window.IntersectionObserver eg

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

Trên Chrome 83

Node.childNodes cung cấp entries, forEach, item, keys,lengthvalues

ParentNode.children cung cấp item, lengthnamedItem

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.