HTML API

本系列的介绍中指出,“HTML 元素是构成文档对象模型的节点”。我们已经讨论了元素节点的类型。在本部分中,我们将介绍用于查询这些节点的元素 API。

DOM 和 AOM

DOM 是一个用于访问和操作文档的 API。DOM 是文档中所有节点的树。有些节点可以有子节点,有些则不可以。该树包含元素及其属性和文本节点。

显示元素和文本节点的 MLW 节点树。

浏览器工具不会提供上述树状可视化图表,但您可以在元素检查器中看到这些节点。

DOM/ARIA。

在浏览器开发者工具中可检查的树形表示法是无障碍树。AOM 基于 DOM;同样,无障碍树包含代表所有标记元素、属性和文本节点的对象:

AOM 示例。

HTML 元素 API

DOM 的中间字母是“object”。就像大多数面向对象编程入门课程中的 personcar 对象示例一样,文档树中的每个节点都是一个可使用 JavaScript 操控的对象。

该浏览器提供了许多 API,可提供原生支持的方法、事件以及属性查询和更新。元素节点包含与元素上设置的所有属性相关的信息。您可以使用 HTML 接口来访问有关元素属性的信息。例如,我们可以使用 HTMLImageElement.alt 获取所有图片的 alt 属性:

let allImages = document.querySelectorAll('img');
allImages.forEach((imageInstance) => {
  console.log(imageInstance.alt);
});

HTML 接口不仅可让您访问元素的属性,还可让您访问更多信息。我们可以找到只读的 HTMLElement.offsetHeight,以获取网页中相对于布局的每个版块的高度。

let allSections = document.querySelectorAll('section');
allSections.forEach((sectionInstance) => {
  console.log(sectionInstance.offsetHeight);
});

如果用户更改设备屏幕方向或以其他方式更改视口的宽度,每个 <section> 的高度都会发生变化,并且 DOM 属性也会随之自动更新。

HTML 接口 API 不仅可用于访问属性值。DOM 可让您深入了解界面的当前状态。HTML API 可以访问所有这些信息。您可以分别通过 HTMLMediaElement.durationHTMLMediaElement.currentTimeHTMLMediaElement.ended 访问视频的长度、当前播放的观看位置,以及视频(或音频)是否已播放完毕。

可用的元素接口

除了一些分区元素外,本系列中到目前为止介绍过的以及尚未介绍的大多数 HTML 元素都具有关联的 DOM 接口。所有元素的基准接口恰当地命名为 ElementHTMLElement 继承自 Element,所有 HTML 元素专用接口都继承自它。某些特定于元素的接口由多个类似元素实现。

接口包括:

命名惯例为“HTML”后跟大驼峰式命名的元素或元素分组,再跟“元素”,但元素或元素分组部分没有遵循确切的模式。不必担心,您无需记住这些内容。 只需知道它们的存在即可,以便在需要时查找它们。

如果您有一系列元素,则还可以使用一些集合接口。例如,HTMLCollection.namedItem() 方法会返回集合中 idname 属性与参数匹配的第一个元素;如果没有元素匹配,则返回 null。

HTMLElement 外,超过 30 个元素没有关联的 DOM 接口,其中包括 <address><article><section><nav><header><footer><aside><hgroup>。许多不支持任何非已废弃的非全局属性的元素都有元素专用接口,例如 HTMLPElement<p> 元素)和 HTMLUnknownElement<😃> 或任何其他未定义的元素),但这些接口不会在从 HTMLElement 继承的属性和方法之上实现任何其他属性或方法,并且未列在上面。

冗余的 API 方法和属性

如果接口与其继承的接口具有相同的方法或属性名称,则继承的方法或属性会覆盖被继承的方法或属性。换句话说,父级方法和属性会替换子级方法和属性。当我们使用 imageInstance.altsectionInstance.offsetHeight 分别访问 HTML 元素 API 中的 altoffsetHeight 属性时,代码无法识别正在访问哪个 API。通常,就像这两个示例一样,这不是问题。

不过,在某些情况下,冗余可能会导致问题。例如,HTMLCollection.length 是只读的,而继承接口 HTMLOptionsCollection 具有具有读写权限的长度属性(仅由 <select>options 属性返回)。HTMLOptionsCollection 可用于设置集合大小。

其他接口

还有一些其他接口可用于操控 DOM 节点的分支位置。EventTarget 接口会向我们提供 addEventListener()removeEventListener(),并会被 NodeWindow 接口继承。反过来,Element、Document 和 DocumentFragment(我们在自定义元素中曾介绍过)接口会继承自 Node,而 HTMLElement 接口会继承自 Element。

node 接口

每种类型的 DOM 节点都由基于 Node 的接口表示,该接口会提供与 DOM 树相关的元素的信息和方法。Node 接口支持查询节点树并向其添加节点。

Douglas Crockford 的著名“遍历 DOM”函数使用了 Node 的 firstChildnextSibling 属性。

const walk_the_DOM = function walk(node, callback) {
  callback(node);
  node = node.firstChild;
  while (node) {
    walk(node, callback);
    node = node.nextSibling;
  }
};

我们在定义自定义元素时使用了 Node 的 appendChild()cloneNode() 方法。Node 接口提供了许多用于查询和操作 DOM 的实用属性和方法。

customElements.define('star-rating',
  class extends HTMLElement {
    constructor() {
      super(); // Always call super first in constructor
      const starRating = document.getElementById('star-rating-template').content;
      const shadowRoot = this.attachShadow({
        mode: 'open'
      });
      shadowRoot.appendChild(starRating.cloneNode(true));
    }
  });

attachShadow() 方法是 Element 接口的方法。此外,还有一个 shadowRoot 接口,用于与文档的主 DOM 树分开呈现的 Shadow DOM API

DocumentHTMLDocument 接口

Document 接口继承自 Node。它表示在浏览器中加载的网页,无论文档是 HTML、SVG、XML、MathML 还是其他格式。Document 接口还会继承自 HTMLDocument 接口。

document 可让您快速访问节点类型,并能够创建特定元素类型(例如 document.bodydocument.styleSheets)的集合。借助 HTMLDocument,您可以访问与文档相关但未在 HTML 节点中找到的信息,例如 Document.locationDocument.lastModifiedDocument.Cookie

您可以根据通过文档界面显示的功能使用多种 API,包括 Drag and Drop APIFullScreen API。两者均继承自 Element

Window 接口

Window 接口除了 DOM 之外,还包含可用于操控 DOM 的全局可用项。Window 提供了 MDN 的 JavaScriptDOM 参考文档中记录的函数、命名空间、对象和构造函数。

Window 接口是包含文档的对象的 API。全局 window 对象是脚本运行的窗口。每个浏览器标签页都包含自己的 Window 对象。Window 接口可以查询标签页的内容以及整个窗口和设备。例如,resizeTo() 方法可用于调整浏览器窗口的大小,devicePixelRatio 属性可用于访问设备显示屏像素。当您访问内容所在的标签页(而非标签页显示的 DOM 树)的相关信息时,该窗口可能是您要查找的界面。

您可以根据通过 Window 接口提供的功能使用多种 API,包括 Web WorkerIndexedDB API。

检查您的理解情况

测试您对 HTML API 相关知识的掌握情况。

DOM 中的 O 代表什么?

已定向。
请重试。
对象
正确!
外连接。
请重试。

哪个界面可以帮助您了解内容所在的标签页的相关信息?

窗口
正确!
文档
请重试。
节点
请重试。