在本教程中,您将了解 JavaScript 中的文档对象模型,通常也称为 DOM 对象模型。

什么是文档对象模型  DOM

文档对象模型 (DOM) 是用于操作 HTML 文档的应用程序编程接口 API。DOM 是跨平台且与语言无关的操作 HTML 和 XML 文档的方法。

DOM 将 HTML 文档表示为节点树。DOM 提供的功能允许您有效地添加、删除和修改文档的某些部分。

作为节点层次结构的文档

DOM 将 HTML 文档表示为节点层次结构。例如以下 HTML 文档:

<html>
    <head>
        <title>JavaScript DOM</title>
    </head>
    <body>
        <p>Hello DOM!</p>
    </body>
</html>

下面的树代表了面的 HTML 文档:

在这棵 DOM 树中,document 是根节点。根节点有一个子节点,即 <html> 元素。<html> 元素称为文档元素。

每个文档只能有一个 document 元素。在 HTML 文档中,document 元素就是 <html> 元素。每个标签都可以由树中的一个节点表示。

节点类型

DOM 树中的每个节点都由节点类型标识。JavaScript 使用整数来确定节点类型。下表说明了节点类型常量:

常量 描述
Node.ELEMENT_NODE 1 Element节点,例如<p>或者<div>
Node.TEXT_NODE 3 Element 内的 Text文本
Node.CDATA_SECTION_NODE 4 CDATASection,比如<!CDATA[[ … ]]>
Node.PROCESSING_INSTRUCTION_NODE 7 XML 文档的 ProcessingInstruction,例如<?xml-stylesheet … ?>
Node.COMMENT_NODE 8 Comment 节点,例如<!-- … -->
Node.DOCUMENT_NODE 9 Document 节点
Node.DOCUMENT_TYPE_NODE 10 DocumentType节点,例如<!DOCTYPE html>
Node.DOCUMENT_FRAGMENT_NODE 11 DocumentFragment节点

要获取节点的类型,请使用节点对象的 nodeType 属性:

node.nodeType

您可以将 nodeType 属性与上述常量进行比较来确定节点类型。例如:

if (node.nodeType == Node.ELEMENT_NODE) {
    // node is the element node
}

nodeName 和 nodeValue 属性

节点有两个重要属性:nodeNamenodeValue 提供关于该节点的信息。这些属性的值取决于节点类型。

例如,如果节点类型是元素节点,则 nodeName 始终与元素的标签名称相同并且nodeValue 始终为 null

因此,最好在使用这些属性之前测试节点类型:

if (node.nodeType == Node.ELEMENT_NODE) {
    let name = node.nodeName; // tag name like <p>
}

节点和元素

有时很容易混淆 NodeElement

节点是 DOM 树中任何对象的通用名称。它可以是任何内置的 DOM 元素,例如文档。或者它可以是 HTML 文档中指定的任何 HTML 标签,例如 <div><p>

元素是具有特定类型 Node.ELEMENT_NODE 的节点,其值等于 1。换句话说,节点是元素的通用名称。

下图说明 NodeElement 之间的关系:

请注意 getElementById()querySelector() 返回的类型是 Element 对象,而 getElementsByTagName() 或者 querySelectorAll() 返回一个节点集合NodeList

节点关系

任何节点都与 DOM 树中的其他节点存在关系。这些关系与传统家族谱中描述的关系相同。

例如,<body><html> 节点的子节点<html><body> 节点的父节点<body> 节点是 <head> 节点的兄弟节点,因为它们共享相同的直接父节点,即元素<html>

下图说明节点之间的关系:

结论

HTML 或 XML 文档可以表示为节点树,就像传统的家族谱一样。每个标签都可以表示为具有特定节点类型的节点。

元素是具有节点类型 Node.ELEMENT_NODE 的节点 。在 DOM 树中,一个节点与其他节点之间存在关系。