Movatterモバイル変換


[0]ホーム

URL:


  1. Web
  2. Web APIs
  3. Document Object Model (DOM)
  4. Anatomy of the DOM

Anatomy of the DOM

The DOM represents an XML or HTML document as a tree. This page introduces the basic structure of the DOM tree and the various properties and methods used to navigate it.

To begin with, we need to introduce some concepts related to trees. A tree is a data structure made up ofnodes. Each node holds somedata. The nodes are organized in a hierarchical way—every node has a singleparent node (except for the root node, which has no parent), and an ordered list of zero or morechild nodes. Now we can define the following:

  • A node with no parent is called theroot of the tree.
  • A node with no children is called aleaf.
  • Nodes that share the same parent are calledsiblings. Siblings belong to the same child node list of their parent, so they have a well-defined order.
  • If we can go from node A to node B by repeatedly following parent links, then A is adescendant of B, and B is anancestor of A.
  • Nodes in a tree are listed intree order by first listing the node itself, then recursively listing each of its child nodes in order (preorder, depth-first traversal).

And here are a few important properties of trees:

  • Every node is associated with a unique root node.
  • If node A is the parent of node B, then node B is a child of node A.
  • Cycles are not allowed: no node can be an ancestor or descendant of itself.

The Node interface and its subclasses

All nodes in the DOM are represented by objects that implement theNode interface. TheNode interface embodies many of the previously defined concepts:

  • TheparentNode property returns the parent node, ornull if the node has no parent.
  • ThechildNodes property returns aNodeList of the child nodes. ThefirstChild andlastChild properties return the first and last elements of this list, respectively, ornull if there are no children.
  • ThegetRootNode() method returns the root of the tree that contains the node, by repeatedly following parent links.
  • ThehasChildNodes() method returnstrue if it has any child nodes, i.e., it is not a leaf.
  • ThepreviousSibling andnextSibling properties return the previous and next sibling nodes, respectively, ornull if there is no such sibling.
  • Thecontains() method returnstrue if a given node is a descendant of the node.
  • ThecompareDocumentPosition() method compares two nodes by tree order. TheComparing nodes section discusses this method in more detail.

You rarely work with plainNode objects—instead, all objects in the DOM implement one of the interfaces that inherit fromNode, which represent additional semantics in the document. The node types restrict what data they contain, and what children types are valid. Consider how the following HTML document is represented in the DOM:

html
<!doctype html><html lang="en">  <head>    <meta charset="utf-8" />    <meta name="viewport" content="width=device-width, initial-scale=1.0" />    <title>Document</title>  </head>  <body>    <h1>Hello, world!</h1>    <p>This is a paragraph.</p>  </body></html>

It produces the following DOM tree:

The DOM tree of the previous HTML document

The root of this DOM tree is aDocument node, which represents the entire document. This node is exposed globally as thedocument variable. This node has two important child nodes:

  • An optionalDocumentType node representing thedoctype declaration. In our case, there is one. This node is also accessible via thedoctype property of theDocument node.
  • An optionalElement node representing the root element. For HTML documents (such as our case), this is typically theHTMLHtmlElement. For SVG documents, this is typically theSVGSVGElement. This node is also accessible via thedocumentElement property of theDocument node.

TheDocumentType node is always a leaf node. TheElement node is where most of the document content is represented. Each element under it, such as<head>,<body>, and<p>, is also represented by anElement node. In fact, each is a subclass ofElement specific to that tag name, defined in the HTML specification, such asHTMLHeadElement andHTMLBodyElement, with additional properties and methods to represent the semantics of that element, but here we focus on the common behaviors of the DOM. TheElement nodes can have otherElement nodes as children, representing nested elements. For example, the<head> element has three children: two<meta> elements and a<title> element. Additionally, elements can also haveText nodes andCDATASection nodes as children, representing text content. For example, the<p> element has a single child, aText node containing the string "This is a paragraph.".Text nodes andCDATASection nodes are always leaf nodes.

All nodes that can have children (Document,DocumentFragment, andElement) allow two types of children:Comment andProcessingInstruction nodes. These nodes are always leaf nodes.

Each element, in addition to having child nodes, can also have attributes, represented asAttr nodes.Attr extend theNode interface, but they are not part of the main tree structure, because they are not the child of any node and their parent node isnull. Instead, they are stored in a separate named node map, accessible via theattributes property of theElement node.

TheNode interface defines anodeType property that indicates the type of the node. To summarize, we introduced the following node types:

Node typenodeType valueValid children (besidesComment andProcessingInstruction)
DocumentNode.DOCUMENT_NODE (9)DocumentType,Element
DocumentTypeNode.DOCUMENT_TYPE_NODE (10)None
ElementNode.ELEMENT_NODE (1)Element,Text,CDATASection
TextNode.TEXT_NODE (3)None
CDATASectionNode.CDATA_SECTION_NODE (4)None
CommentNode.COMMENT_NODE (8)None
ProcessingInstructionNode.PROCESSING_INSTRUCTION_NODE (7)None
AttrNode.ATTRIBUTE_NODE (2)None

Note:You may notice we skipped some node types here. TheNode.ENTITY_REFERENCE_NODE (5),Node.ENTITY_NODE (6), andNode.NOTATION_NODE (12) values are no longer used, while theNode.DOCUMENT_FRAGMENT_NODE (11) value will be introduced inBuilding and updating the DOM tree.

Data of each node

Each node type has its own way of representing the data it holds. TheNode interface itself defines three properties related to data, summarized in the following table:

Node typenodeNamenodeValuetextContent
Document"#document"nullnull
DocumentTypeItsname (e.g.,"html")nullnull
ElementItstagName (e.g.,"HTML","BODY")nullConcatenation of all its text node descendants in tree order
Text"#text"ItsdataItsdata
CDATASection"#cdata-section"ItsdataItsdata
Comment"#comment"ItsdataItsdata
ProcessingInstructionItstargetItsdataItsdata
AttrItsnameItsvalueItsvalue

Document

TheDocument node does not hold any data itself, so itsnodeValue andtextContent are alwaysnull. ItsnodeName is always"#document".

TheDocument does define some metadata about the document, coming from the environment (for example, the HTTP response that served the document):

  • TheURL anddocumentURI properties return the document's URL.
  • ThecharacterSet property returns the character encoding used by the document, such as"UTF-8".
  • ThecompatMode property returns the rendering mode of the document, either"CSS1Compat" (standards mode) or"BackCompat" (quirks mode).
  • ThecontentType property returns themedia type of the document, such as"text/html" for HTML documents.

DocumentType

ADocumentType in the document looks like this:

xml
<!doctype name PUBLIC "publicId" "systemId">

There are three parts you can specify, which correspond to the three properties of theDocumentType node:name,publicId, andsystemId. For HTML documents, the doctype is always<!doctype html>, so thename is"html" and bothpublicId andsystemId are empty strings.

Element

AnElement in the document looks like this:

html
<p>This is a paragraph.</p>

In addition to the contents, there are two parts you can specify: the tag name and the attributes. The tag name corresponds to thetagName property of theElement node, which is"P" in this case (note that it is always in uppercase for HTML elements). The attributes correspond to theAttr nodes stored in theattributes property of theElement node. We will discuss attributes in more detail in theElement and its attributes section.

TheElement node does not hold any data itself, so itsnodeValue is alwaysnull. ItstextContent is the concatenation of all its text node descendants in tree order, which is"This is a paragraph." in this case. For the following element:

html
<div>Hello, <span>world</span>!</div>

ThetextContent is"Hello, world!", concatenating the text node"Hello, ", the text node"world" inside the<span> element, and the text node"!".

CharacterData

Text,CDATASection,Comment, andProcessingInstruction all inherit from theCharacterData interface, which is a subclass ofNode. TheCharacterData interface defines a single property,data, which holds the text content of the node. Thedata property is also used to implement thenodeValue andtextContent properties of these nodes.

ForText andCDATASection, thedata property holds the text content of the node. In the following document (note that we use an SVG document, because HTML does not allow CDATA sections):

svg
<text>Some text</text><style><![CDATA[h1 { color: red; }]]></style>

The text node inside the<text> element has"Some text" asdata, and the CDATA section inside the<style> element has"h1 { color: red; }" asdata.

ForComment, thedata property holds the content of the comment, starting after the<!-- and ending before the-->. For example, in the following document:

html
<!-- This is a comment -->

The comment node has" This is a comment " asdata.

ForProcessingInstruction, thedata property holds the content of the processing instruction, starting after the target and ending before the?>. For example, in the following document:

xml
<?xml-stylesheet type="text/xsl" href="style.xsl"?>

The processing instruction node has'type="text/xsl" href="style.xsl"' asdata, and"xml-stylesheet" as itstarget.

In addition, theCharacterData interface defines thelength property, which returns the length of thedata string, and thesubstringData() method, which returns a substring of thedata.

Attr

For the following element:

html
<p>This is a paragraph.</p>

The<p> element has two attributes, represented by twoAttr nodes. Each attribute consists of a name and a value, corresponding to thename andvalue properties. The first attribute has"class" asname and"note" asvalue, while the second attribute has"id" asname and"intro" asvalue.

Element and its attributes

As previously mentioned, the attributes of anElement node are represented byAttr nodes, which are stored in a separate named node map, accessible via theattributes property of theElement node. ThisNamedNodeMap interface defines three important properties:

  • length, which returns the number of attributes.
  • item() method, which returns theAttr at a given index.
  • getNamedItem() method, which returns theAttr with a given name.

TheElement interface also defines several methods to work with attributes directly, without needing to access the named node map:

You can also access the owner element of an attribute via theownerElement property of theAttr node.

There are two special attributes,id andclass, which have their own properties on theElement interface:id andclassName, thatreflect the value of the corresponding attribute. In addition, theclassList property returns aDOMTokenList representing the list of classes in theclass attribute.

Working with the element tree

BecauseElement nodes form the backbone of the document structure, you can specifically traverse the element nodes, skipping other nodes (such asText andComment).

  • For all nodes, theparentElement property returns the parent node if it is anElement, ornull if the parent is not anElement (for example, if the parent is aDocument). This is in contrast toparentNode, which returns the parent node regardless of its type.
  • ForDocument,DocumentFragment, andElement, thechildren property returns anHTMLCollection of only the childElement nodes. This is in contrast tochildNodes, which returns all child nodes. ThefirstElementChild andlastElementChild properties return the first and last elements of this collection, respectively, ornull if there are no child elements. ThechildElementCount property returns the number of child elements.
  • ForElement andCharacterData, thepreviousElementSibling andnextElementSibling properties return the previous and next sibling node that is anElement, ornull if there is no such sibling. This is in contrast topreviousSibling andnextSibling, which may return any type of sibling node.

Comparing nodes

There are three important methods that compare nodes:isEqualNode(),isSameNode(),compareDocumentPosition().

TheisSameNode() method is legacy. Now, it behaves like thestrict equality operator (===), returningtrue if and only if the two nodes are the same object.

TheisEqualNode() method compares two nodes structurally. Two nodes are considered equal if they have the same type, the same data, and their child nodes are also equal at each index. In theData of each node section, we already defined the data relevant for each node type:

  • ForDocument, there is no data, so only the child nodes need to be compared.
  • ForDocumentType, thename,publicId, andsystemId properties need to be compared.
  • ForElement, thetagName (more accurately, thenamespaceURI,prefix, andlocalName; we will introduce these in theXML namespaces guide) and the attributes need to be compared.
  • ForAttr, thename (more accurately, thenamespaceURI,prefix, andlocalName; we will introduce these in theXML namespaces guide) andvalue properties need to be compared.
  • For allCharacterData nodes (Text,CDATASection,Comment, andProcessingInstruction), thedata property needs to be compared. ForProcessingInstruction, thetarget property also needs to be compared.

Thea.compareDocumentPosition(b) method compares two nodes by tree order. It returns a bitmask indicating their relative positions. The possible cases are:

  • Returns0 ifa andb are the same node.
  • If the two nodes are both attributes of the same element node, returnsNode.DOCUMENT_POSITION_PRECEDING | Node.DOCUMENT_POSITION_IMPLEMENTATION_SPECIFIC (34) ifa precedesb in the attribute list, orNode.DOCUMENT_POSITION_FOLLOWING | Node.DOCUMENT_POSITION_IMPLEMENTATION_SPECIFIC (36) ifa followsb. If either node is an attribute, the owner element is used for further comparisons.
  • If the two nodes don't have the same root node, returns eitherNode.DOCUMENT_POSITION_DISCONNECTED | Node.DOCUMENT_POSITION_IMPLEMENTATION_SPECIFIC | Node.DOCUMENT_POSITION_PRECEDING (35) orNode.DOCUMENT_POSITION_DISCONNECTED | Node.DOCUMENT_POSITION_IMPLEMENTATION_SPECIFIC | Node.DOCUMENT_POSITION_FOLLOWING (37). Which one is returned is implementation-specific.
  • Ifa is an ancestor ofb (including whenb is an attribute ofa), returnsNode.DOCUMENT_POSITION_CONTAINS | Node.DOCUMENT_POSITION_PRECEDING (10).
  • Ifa is a descendant ofb (including whena is an attribute ofb), returnsNode.DOCUMENT_POSITION_CONTAINED_BY | Node.DOCUMENT_POSITION_FOLLOWING (20).
  • Ifa precedesb in tree order, returnsNode.DOCUMENT_POSITION_PRECEDING (2).
  • Ifa followsb in tree order, returnsNode.DOCUMENT_POSITION_FOLLOWING (4).

Bitmask values are used, so you can use a bitwise AND operation to check for specific relationships. For example, to check ifa precedesb, you can do:

js
if (a.compareDocumentPosition(b) & Node.DOCUMENT_POSITION_PRECEDING) {  // a precedes b}

Which accounts for the cases ofa andb being attributes of the same element,a being an ancestor ofb, anda precedingb in tree order.

Summary

Here are all the features we've introduced so far. There are a lot, but they are all useful in different scenarios.

Help improve MDN

Learn how to contribute

This page was last modified on byMDN contributors.


[8]ページ先頭

©2009-2026 Movatter.jp