HTML DOM API
============

**HTML DOM API** 由一系列接口组成，它们定义了 HTML 中每个元素的功能，以及它们所依赖的任何支持类型和接口。

HTML DOM API 的功能包括：

* 通过 DOM 访问和控制 HTML 元素。
* 访问和操作表单数据。
* 与 2D 图像的内容，以及 HTML `<canvas>` 元素的上下文进行交互，例如在其上绘制。
* 管理连接到 HTML 媒体元素的媒体（`<audio>` 和 `<video>`）。
* 在网页上拖放内容。
* 访问浏览器导航历史记录。
* 支持和关联其他 API 的接口，例如 Web 组件、Web Storage、Web Worker、WebSocket 和 Server-sent 事件。
HTML DOM 概念和用法
--------------

在本文中，我们将重点关注与 HTML 元素交互的 HTML DOM 部分。其他领域的讨论，例如拖放、WebSocket、Web Storage 等，可以在这些 API 的文档中找到。

### HTML 文档的结构

文档对象模型（DOM）是一种描述文档结构的架构；每个文档都由 `Document` 接口的实例表示。而一个文档则由**节点**层次树组成，其中每个节点，都代表文档中单个对象（如元素或文本节点）的基本记录。

节点可以组织文档结构，提供将其他节点分组，以及构建层级结构的点的方法。其他节点可能代表文档的可见组件。每个节点都基于 `Node` 接口，该接口提供了获取有关节点信息，以及创建、删除和组织 DOM 中节点的方法。

节点本身不包含实际显示在文档中的内容，它们是空容器。节点呈现视觉内容的能力，是由 `Element` 接口引入的。一个 `Element` 对象实例，代表着使用 HTML 或 SVG 等 XML 词汇创建的文档中的单个元素。

例如，考虑一个包含两个元素的文档，其中一个元素内嵌了另外两个元素：

![窗口中，内部包含元素的文档结构](/zh-CN/docs/Web/API/HTML_DOM_API/dom-structure.svg)

虽然 `Document` 接口是作为 DOM 规范的一部分定义的，但 HTML 规范显著增强了它，添加了特定于 Web 浏览器上下文中，使用 DOM 以及表示 HTML 文档的信息。

HTML 标准添加到 `Document` 中的内容包括：

* 在加载页面时，支持访问 HTTP 标头提供的各种信息，例如文档加载的位置、cookie、修改日期、引用站点等。
* 可以访问文档 `<head>` 块和 body 中元素的列表，以及包含在文档中的图像、链接、脚本等列表。
* 支持通过检查焦点和对可编辑内容执行命令来与用户交互。
* HTML 标准定义的文档事件处理器，允许访问鼠标和键盘事件、拖放、媒体控制等。
* 可以传递到元素和文档的事件处理器；目前仅包括复制、剪切和粘贴操作。
### HTML 元素接口

通过引入 `HTMLElement` 接口，`Element` 接口被进一步调整为专门表示 HTML 元素，所有更具体的 HTML 元素类都继承自它。这扩展了 `Element` 类，以向元素节点添加了特定于 HTML 的通用特性。`HTMLElement` 添加的属性包括 `hidden` 和 `innerText` 等。

HTML 文档是 DOM 树，其中每个节点都是一个由 `HTMLElement` 接口表示的 HTML 元素。`HTMLElement` 类实现了 `Node`，因此每个元素也是一个节点（但反过来不成立）。这样，由 `Node` 接口实现的结构特性也可用于 HTML 元素中，允许它们相互嵌套、创建和删除、移动等。

`HTMLElement` 接口是通用的，但是它仅提供所有 HTML 元素共有的功能，例如元素的 ID、坐标、构成元素的 HTML 代码、滚动位置等信息。

为了扩展核心 `HTMLElement` 接口的功能，以提供特定元素所需的特性，`HTMLElement` 类被子类化以添加所需的属性和方法。例如，`<canvas>` 元素由类型为 `HTMLCanvasElement` 的对象表示。`HTMLElement` 通过添加诸如 `height` 等属性和 `getContext()` 等方法来增强 `HTMLElement` 类型，从而提供特定于 canvas 的特性。

HTML 元素类的总体继承关系如下：

![HTML 元素的接口层次结构](/zh-CN/docs/Web/API/HTML_DOM_API/html-dom-hierarchy.svg)

因此，元素继承其所有祖先的属性和方法。例如，考虑 `<a>` 元素，在 DOM 中由类型为 `HTMLAnchorElement` (en-US) 的对象表示。元素包括了该类文档中，`Anchor` 特定的属性和方法。但也包括 `HTMLElement`、`Element` 以及 `Node` 定义的内容，最后是 `EventTarget` 定义的内容。

每一层级都定义了元素实用性的一个关键方面。从 `Node` 开始，该元素继承了有关该元素能否被另一个元素包含，以及自身包含其他元素的概念。特别重要的是从 `EventTarget` 继承的：接收和处理事件（如鼠标点击、播放和暂停事件等）的能力。

有一些元素具有共性，因此还有一个额外的中介类型。例如，`<audio>` 和 `<video>` 元素都呈现音视频媒体。相应的 `HTMLAudioElement` 和 `HTMLVideoElement` 类型都基于通用类型 `HTMLMediaElement`，后者又基于 `HTMLElement` 等等。`HTMLMediaElement` 定义了音频和视频元素之间共同拥有的方法和属性。

这些特定于元素的接口构成了大部分 HTML DOM API，并且是本文的重点。要了解 DOM 的实际结构，请参阅 DOM 概述。

HTML DOM 的目标受众
--------------

HTML DOM 所暴露的特性是 web 开发人员工具箱中最常用的 API 之一。除了最简单的 web 应用程序外，几乎所有 web 应用程序都会使用 HTML DOM 的某些特性。

HTML DOM API 接口
---------------

HTML DOM API 中的大多数接口，几乎一对一地映射到单个 HTML 元素，或是类似功能的少量元素组。此外，HTML DOM API 还包括一些接口和类型，以支持 HTML 元素接口。

### HTML 元素接口

这些接口代表特定的 HTML 元素（或者属性、方法与它们相关、相同的元素）。

* `HTMLAnchorElement` (en-US)
* `HTMLAreaElement`
* `HTMLAudioElement`
* `HTMLBaseElement`
* `HTMLBodyElement`
* `HTMLBRElement`
* `HTMLButtonElement`
* `HTMLCanvasElement`
* `HTMLDataElement` (en-US)
* `HTMLDataListElement` (en-US)
* `HTMLDetailsElement`
* `HTMLDialogElement`
* `HTMLDirectoryElement`
* `HTMLDivElement`
* `HTMLDListElement` (en-US)
* `HTMLElement`
* `HTMLEmbedElement` (en-US)
* `HTMLFieldSetElement`
* `HTMLFormElement`
* `HTMLHRElement` (en-US)
* `HTMLHeadElement`
* `HTMLHeadingElement` (en-US)
* `HTMLHtmlElement`
* `HTMLIFrameElement`
* `HTMLImageElement`
* `HTMLInputElement`
* `HTMLLabelElement` (en-US)
* `HTMLLegendElement` (en-US)
* `HTMLLIElement`
* `HTMLLinkElement` (en-US)
* `HTMLMapElement` (en-US)
* `HTMLMediaElement`
* `HTMLMenuElement` (en-US)
* `HTMLMetaElement` (en-US)
* `HTMLMeterElement` (en-US)
* `HTMLModElement` (en-US)
* `HTMLObjectElement` (en-US)
* `HTMLOListElement` (en-US)
* `HTMLOptGroupElement`
* `HTMLOptionElement`
* `HTMLOutputElement` (en-US)
* `HTMLParagraphElement`
* `HTMLPictureElement` (en-US)
* `HTMLPreElement` (en-US)
* `HTMLProgressElement` (en-US)
* `HTMLQuoteElement` (en-US)
* `HTMLScriptElement`
* `HTMLSelectElement` (en-US)
* `HTMLSlotElement`
* `HTMLSourceElement` (en-US)
* `HTMLSpanElement`
* `HTMLStyleElement`
* `HTMLTableCaptionElement` (en-US)
* `HTMLTableCellElement` (en-US)
* `HTMLTableColElement` (en-US)
* `HTMLTableElement`
* `HTMLTableRowElement` (en-US)
* `HTMLTableSectionElement` (en-US)
* `HTMLTemplateElement`
* `HTMLTextAreaElement`
* `HTMLTimeElement` (en-US)
* `HTMLTitleElement` (en-US)
* `HTMLTrackElement` (en-US)
* `HTMLUListElement` (en-US)
* `HTMLUnknownElement`
* `HTMLVideoElement`

#### 废弃的 HTML 元素接口

* `HTMLMarqueeElement` (en-US) 
已弃用

#### 过时的 HTML 元素接口

* `HTMLFontElement` (en-US) 
已弃用
* `HTMLFrameElement` 
已弃用
* `HTMLFrameSetElement` (en-US) 
已弃用
* `HTMLIsIndexElement` 
已弃用
* `HTMLMenuItemElement` (en-US) 
已弃用
### Web 应用程序和浏览器集成接口

这些接口提供了访问包含 HTML 的浏览器窗口和文档的方式，以及访问浏览器状态、可用插件（如果有）和各种配置选项的方式。

* `BarProp` (en-US)
* `Navigator`
* `Window`

#### 废弃的 Web 应用程序和浏览器集成接口

* `External` 
已弃用

#### 过时的 Web 应用程序和浏览器集成接口

* `ApplicationCache` 
已弃用
* `Plugin` 
已弃用
* `PluginArray` (en-US) 
已弃用
### 表单支持接口

这些接口提供了创建和管理表单所需的结构和功能，包括 `<form>` 和 `<input>` 元素。

* `FormDataEvent` (en-US)
* `HTMLFormControlsCollection` (en-US)
* `HTMLOptionsCollection` (en-US)
* `RadioNodeList` (en-US)
* `ValidityState`
### Canvas 和图像接口

这些接口代表了 Canvas API 以及 `<img>` 元素和 `<picture>` 元素使用的对象。

* `CanvasGradient`
* `CanvasPattern`
* `CanvasRenderingContext2D`
* `ImageBitmap`
* `ImageBitmapRenderingContext`
* `ImageData`
* `OffscreenCanvas`
* `OffscreenCanvasRenderingContext2D` (en-US)
* `Path2D`
* `TextMetrics`
### 媒体接口

媒体接口提供对媒体元素（`<audio>` 和 `<video>`）内容的 HTML 访问。

* `AudioTrack`
* `AudioTrackList` (en-US)
* `MediaError` (en-US)
* `TextTrack` (en-US)
* `TextTrackCue` (en-US)
* `TextTrackCueList` (en-US)
* `TextTrackList` (en-US)
* `TimeRanges`
* `TrackEvent` (en-US)
* `VideoTrack` (en-US)
* `VideoTrackList` (en-US)
### 拖放接口

这些接口被 HTML 拖放 API 用于表示单个或一组可拖动（或已拖动）元素，并处理拖放过程。

* `DataTransfer`
* `DataTransferItem`
* `DataTransferItemList`
* `DragEvent`
### 页面历史接口

History API 接口允许你访问有关浏览器历史记录的信息，并通过历史记录将浏览器的当前标签页向前或向后跳转。

* `BeforeUnloadEvent`
* `HashChangeEvent`
* `History`
* `Location`
* `PageTransitionEvent`
* `PopStateEvent` (en-US)
### Web 组件接口

这些接口被 Web 组件 API 用于创建和管理可用的自定义元素。

* `CustomElementRegistry`
### 杂项和支持接口

这些支持对象类型在 HTML DOM API 中以各种方式被使用。此外，`PromiseRejectionEvent` 表示当 JavaScript `Promise` 被拒绝时传递的事件。

* `DOMStringList`
* `DOMStringMap`
* `ErrorEvent`
* `HTMLAllCollection` (en-US)
* `MimeType`
* `MimeTypeArray` (en-US)
* `PromiseRejectionEvent`
### 属于其他 API 的接口

有几个接口在 HTML 规范中在技术上被定义，但实际上是其他 API 的一部分。

#### Web Storage 接口

Web Storage API 提供了网站在用户设备上临时或永久存储数据以便后续复用的能力。

* `Storage`
* `StorageEvent`

#### Web Worker 接口

这些接口被 Web Worker API 用于建立 Worker 与应用及其内容交互的能力，同时也支持窗口或应用之间的消息传递。

* `BroadcastChannel`
* `DedicatedWorkerGlobalScope`
* `MessageChannel`
* `MessageEvent`
* `MessagePort`
* `SharedWorker`
* `SharedWorkerGlobalScope` (en-US)
* `Worker`
* `WorkerGlobalScope` (en-US)
* `WorkerLocation` (en-US)
* `WorkerNavigator` (en-US)

#### WebSocket 接口

这些接口由 HTML 规范定义，被 WebSocket API 使用。

* `CloseEvent`
* `WebSocket`

#### Server-sent 事件接口

`EventSource` 接口表示发送或正在发送 server-sent 事件的源。

* `EventSource`
示例
--

在这个示例中，`<input>` 元素的 `input` 事件被监听，以便根据给定字段当前是否有值，来更新表单“提交”按钮的状态。

### JavaScript


```js
const nameField = document.getElementById("userName");
const sendButton = document.getElementById("sendButton");

sendButton.disabled = true;
// [提示：这是被禁用的，因为它会导致文章始终加载此示例，并将其聚焦和滚动到视图中]
//nameField.focus();

nameField.addEventListener("input", (event) => {
  const elem = event.target;
  const valid = elem.value.length != 0;

  if (valid && sendButton.disabled) {
    sendButton.disabled = false;
  } else if (!valid && !sendButton.disabled) {
    sendButton.disabled = true;
  }
});
```


这段代码使用 `Document` 接口的 `getElementById()` 方法，获取 ID 为 `userName` 和 `sendButton` 的 `<input>` 元素的 DOM 对象。通过这些对象，我们可以访问提供信息的属性和方法，并获得对这些元素的控制权。

“发送”按钮的 `HTMLInputElement` 对象的 `disabled` (en-US) 属性被设置为 `true`，这将禁用“发送”按钮，使其无法点击。此外，通过调用继承自 `HTMLElement` 的 `focus()` (en-US) 方法，用户名输入字段成为活动焦点。

然后调用 `addEventListener()` 来为用户名输入添加一个 `input` 事件的处理器。这段代码检测当前输入值的长度；如果它是零，则禁用“发送”按钮（如果尚未禁用）。否则，该代码确保按钮已启用。

有了这个设置，只要用户名输入框中有值，“发送”按钮就会一直处于启用状态，当为空时则禁用。

### HTML

表单的 HTML 如下：


```html
<p>请提供以下信息。标有“*”的项目为必填项。</p>
<form action="" method="get">
  <p>
    <label for="userName" required>用户名：</label>
    <input type="text" id="userName" /> (*)
  </p>
  <p>
    <label for="email">邮箱：</label>
    <input type="email" id="userEmail" />
  </p>
  <input type="submit" value="发送" id="sendButton" />
</form>
```

### 结果

规范
--

| Specification |
| --- |
| HTML Standard # htmlelement |

浏览器兼容性
------

BCD tables only load in the browser with JavaScript enabled. Enable JavaScript to view data.

参见
--

### 参考

* HTML 元素参考
* HTML 属性参考
* 文档对象模型（DOM）参考
### 指南

* 操作文档：操作 DOM 的入门指南。