在本系列的介绍中,它说“HTML 元素是构成 文档对象模型 的节点。”我们已经讨论了元素节点的类型。在本节中,我们将讨论启用查询这些节点的元素 API。
DOM 和 AOM
DOM 是用于访问和操作文档的 API。DOM 是文档中所有节点的树。有些节点可以有子节点,有些则不能。树包括元素及其属性和文本节点。
浏览器工具不提供像上面那样的树状可视化效果,但您可以在元素检查器中看到节点。
可以在浏览器开发者工具中检查的树状表示是无障碍功能树。AOM 基于 DOM;类似地,无障碍功能树包含表示所有标记元素、属性和文本节点的对象
HTML 元素 API
DOM 的中间字母是“对象”。就像大多数面向对象编程入门课程中的 person
或 car
对象示例一样,文档树中的每个节点都是可以使用 JavaScript 操作的对象。
浏览器提供了许多 API,这些 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 提供了对 UI 当前状态的深入了解。HTML API 可以访问所有这些信息。您可以使用 HTMLMediaElement.duration
、HTMLMediaElement.currentTime
和 HTMLMediaElement.ended
分别访问视频的长度、视图在当前播放中的位置以及视频(或音频)是否已播放完毕。
可用的元素接口
到目前为止,在本系列中我们已经介绍过并且尚未介绍的大多数 HTML 元素,除了某些分段元素之外,都具有关联的 DOM 接口。所有元素的基本接口都恰如其分地命名为 Element。HTMLElement
继承自 Element,所有特定于 HTML 元素的接口都继承自它。某些特定于元素的接口由多个类似的元素实现。
这些接口包括
HTMLAnchorElement
-<a>
HTMLAreaElement
-<area>
HTMLAudioElement
-<audio>
HTMLBaseElement
-<base>
HTMLButtonElement
-<button>
HTMLCanvasElement
-<canvas>
HTMLDataElement
-<data>
HTMLDataListElement
-<datalist>
HTMLDetailsElement
-<details>
HTMLDialogElement
-<dialog>
HTMLEmbedElement
-<embed>
HTMLFieldSetElement
-<fieldset>
HTMLFormElement
-<form>
HTMLHtmlElement
-<html>
HTMLIFrameElement
-<iframe>
HTMLImageElement
-<img>
HTMLInputElement
-<input>
HTMLLabelElement
-<label>
HTMLLegendElement
-<legend>
HTMLLIElement
-<li>
HTMLLinkElement
-<link>
HTMLMapElement
-<map>
HTMLMediaElement
-<audio>
,<video>
HTMLMenuElement
-<menu>
HTMLMetaElement
-<meta>
HTMLMeterElement
-<meter>
HTMLModElement
-<ins>
,<del>
HTMLObjectElement
-<object>
HTMLOListElement
-<ol>
HTMLOptGroupElement
-<optgroup>
HTMLOptionElement
-<option>
HTMLOutputElement
-<output>
HTMLPictureElement
-<picture>
HTMLProgressElement
-<progress>
HTMLQuoteElement
-<q>
,<blockquote>
,<cite>
HTMLScriptElement
-<script>
HTMLSelectElement
-<select>
HTMLSlotElement
-<slot>
HTMLSourceElement
-<source>
HTMLStyleElement
-<style>
HTMLTableCellElement
-<td>
,<th>
HTMLTableColElement
-<col>
,<colgroup>
HTMLTableElement
-<table>
HTMLTableRowElement
-<tr>
HTMLTableSectionElement
-<thead>
,<tbody>
,<tfoot>
HTMLTemplateElement
-<template>
HTMLTextAreaElement
-<textarea>
HTMLTimeElement
-<time>
HTMLTitleElement
-<title>
HTMLTrackElement
-<track>
HTMLVideoElement
-<video>
命名约定是“HTML”,后跟元素或元素分组(采用大驼峰命名法),再后跟“Element”,但元素或元素分组部分没有确切的模式。不用担心。无需记住这些。重要的是要知道它们存在,以便在需要时可以查找它们。
如果您有一个元素集合,则还有一些集合接口。例如,HTMLCollection.namedItem()
方法返回集合中第一个 id
或 name
属性与参数匹配的元素;如果没有任何元素匹配,则返回 null。
超过 30 个元素没有关联的 DOM 接口,除了 HTMLElement
,包括 <address>
、<article>
、<section>
、<nav>
、<header>
、<footer>
、<aside>
和 <hgroup>
。许多不支持任何非弃用、非全局属性的元素都具有特定于元素的接口,例如 HTMLPElement
(<p>
元素)和 HTMLUnknownElement
(<😃>
或任何其他未定义的元素),但这些接口没有在从 HTMLElement
继承的属性和方法之上实现任何其他属性或方法,并且未在上面列出。
冗余 API 方法和属性
如果一个接口具有与其继承的接口相同的方法或属性名称,则继承的方法或属性将覆盖继承的方法或属性。换句话说,父方法和属性会覆盖子方法和属性。当我们在 HTML 元素 API 中分别使用 imageInstance.alt
和 sectionInstance.offsetHeight
访问 alt
和 offsetHeight
属性时,代码没有标识正在访问哪个 API。通常,与这两个示例一样,这不是问题。
但是,在某些情况下,冗余可能会导致问题。例如,HTMLCollection.length
是只读的,而继承的接口 HTMLOptionsCollection
具有长度属性(仅由 <select>
的 options
属性返回),具有读写访问权限。HTMLOptionsCollection
可用于设置集合大小。
其他接口
还有其他接口可以操作 DOM 节点的分支位置。EventTarget
接口为我们提供了 addEventListener()
和 removeEventListener()
,它由 Node
和 Window
接口继承。反过来,Element、Document 和 DocumentFragment(我们在 自定义元素 中看到过)接口从 Node 继承,而 HTMLElement 接口从 Element 继承。
node
接口
每种类型的 DOM 节点都由基于 Node 的接口表示,该接口提供了与 DOM 树相关的元素的信息和方法。Node
接口支持查询节点并将节点添加到节点树。
Douglas Crockford 著名的“walk the DOM”函数使用了 Node 的 firstChild
和 nextSibling
属性。
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。
Document
和 HTMLDocument
接口
Document
接口继承自 Node
。它表示浏览器中加载的网页,无论文档是 HTML、SVG、XML、MathML 还是其他类型。Document
接口也继承自 HTMLDocument
接口。
document
可以快速访问节点类型,并能够创建特定元素类型的集合,例如 document.body
和 document.styleSheets
。HTMLDocument 支持访问与文档相关但 HTML 节点中找不到的信息,例如 Document.location
、Document.lastModified
和 Document.Cookie
。
基于通过 document 接口公开的功能,有多个 API 可用,包括 拖放 API 和 全屏 API。两者都继承自 Element
。
Window
接口
Window 接口包括超出 DOM 范围的全局可用项,这些项可用于操作 DOM。Window 提供了 MDN 的 JavaScript 和 DOM 参考 中记录的函数、命名空间、对象和构造函数。
Window 接口是包含文档的对象的 API。全局 window
对象是脚本正在运行的窗口。每个浏览器标签页都包含自己的 Window 对象。Window 接口可以查询标签页的内容以及整个窗口和设备。例如,resizeTo()
方法可用于调整浏览器窗口的大小,devicePixelRatio
属性提供对设备显示像素的访问权限。当访问有关标签页的内容而不是标签页显示的 DOM 树的信息时,窗口很可能是您要查找的接口。
基于通过 Window 接口公开的功能,有多个 API 可用,包括 Web Workers 和 IndexedDB API。
检查您的理解
测试您对 HTML API 的知识。
DOM 中的 O 代表什么?
哪个接口可以帮助您找出有关内容所在的标签页的信息?