在本系列的簡介中,我們說明瞭「HTML 元素是構成文件物件模型的節點。」 我們討論了元素節點的類型本節將介紹哪些元素 API 可讓您查詢這些節點。
DOM 和 AOM
DOM 是一個用來存取和操控文件的 API,DOM 是文件中所有節點的樹狀結構。部分節點可以有子項,其他節點則不行。樹狀結構包含元素、元素屬性和文字節點。
瀏覽器工具不提供類似上方的樹狀結構,但您可以在元素檢查器中查看節點。
您可在瀏覽器開發人員工具中檢查的樹狀結構表示法是無障礙樹狀結構。AOM 是以 DOM 為基礎;同理,無障礙樹狀結構包含代表所有標記元素、屬性和文字節點的物件:
HTML 元素 API
DOM 的中間字母是「object」。就像大部分物件導向程式設計類別簡介的 person
或 car
物件範例一樣,文件樹狀結構中的每個節點都是可透過 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 可讓您深入瞭解 UI 目前的狀態。HTML API 可以存取這些資訊。您可以分別存取影片的長度、觀看次數在目前播放中的位置,以及影片 (或音訊) 已分別透過 HTMLMediaElement.duration
、HTMLMediaElement.currentTime
和 HTMLMediaElement.ended
播放。
可用的元素介面
本系列目前為止談到的大部分 HTML 元素,但除了部分區段元素以外,還未提及其他的 DOM 介面。所有元素的基本介面均命名為「元素」。HTMLElement
繼承自元素,所有 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
-<video>
<audio>
HTMLMenuElement
-<menu>
HTMLMetaElement
-<meta>
HTMLMeterElement
-<meter>
HTMLModElement
-<del>
<ins>
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
-<th>
<td>
HTMLTableColElement
-<colgroup>
<col>
HTMLTableElement
-<table>
HTMLTableRowElement
-<tr>
HTMLTableSectionElement
-<thead>
,<tbody>
,<tfoot>
HTMLTemplateElement
-<template>
HTMLTextAreaElement
-<textarea>
HTMLTimeElement
-<time>
HTMLTitleElement
-<title>
HTMLTrackElement
-<track>
HTMLVideoElement
-<video>
命名慣例是「HTML」,後面接著是以駝峰式大小寫命名的元素或元素分組,後面接著「元素」,但元素或元素組的命名方式沒有任何完全相同的模式。請放心,您不需要特別記得這些程式碼。您必須知道它們存在,才能在需要時查詢。
如果您有一系列元素,系統也提供收集介面。舉例來說,HTMLCollection.namedItem()
方法會傳回集合中 id
或 name
屬性與參數相符的第一個元素;如果沒有相符的元素,則會傳回空值。
超過 30 個元素沒有 HTMLElement
以外的相關聯 DOM 介面,包括 <address>
、<article>
、<section>
、<nav>
、<header>
、<footer>
、<aside>
和 <hgroup>
。許多不支援任何未淘汰的屬性都具有特定元素介面,例如 HTMLPElement
(<p>
元素) 和 HTMLUnknownElement
(<😃>
或任何其他未定義的元素),但這些介面不會在繼承自 HTMLElement
的屬性和方法上方實作任何其他屬性或方法,且並未列於上方。
備援 API 方法和屬性
如果介面與沿用的介面具有相同的方法或屬性名稱,繼承方法或屬性會覆寫繼承方法。我們分別使用 imageInstance.alt
和 sectionInstance.offsetHeight
存取上述 alt
和 offsetHeight
屬性時,程式碼並無法識別存取的 API。
一般來說,這並非問題,與以上兩個例子一樣。但其實沒問題。舉例來說,HTMLCollection.length
屬於唯讀性質,而沿用的 HTMLOptionsCollection
介面長度屬性 (僅由 <select>
的 options
屬性傳回) 也可用來設定集合大小。
其他介面
還有其他介面能控制 DOM 節點的分支位置。提供 addEventListener()
和 removeEventListener()
的 EventTarget
介面是由 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;
}
};
我們使用節點的 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()
方法是元素介面的方法。此外,Shadow DOM API 也提供 shadowRoot
介面,可與文件的主要 DOM 樹狀結構分開轉譯。
Document
和 HTMLDocument
介面
Document
介面繼承自 Node
。它代表在瀏覽器中載入的網頁,無論文件是 HTML、SVG、XML、MathML 或其他都可以。Document
介面也會沿用 HTMLDocument
介面。
document
可讓您快速存取節點類型,以及建立特定元素類型的集合,例如 document.body
和 document.styleSheets
。可針對 HTML 節點中找不到的文件 (例如 Document.location
、Document.lastModified
和 Document.Cookie
) 存取文件相關資訊。
有許多 API 以文件介面顯示的功能為基礎,包括 Drag and Drop API 和 FullScreen API。兩者都繼承自 Element
。
Window
介面
除了 DOM 之外,Window 介面還包含可用於操控 DOM 的全球項目。Window 提供如 MDN 的 JavaScript 和 DOM 參考資料記錄的函式、命名空間、物件和建構函式。
視窗介面是包含文件物件的 API。全域 window
物件是指指令碼執行的視窗。每個瀏覽器分頁都有各自的 Window 物件。視窗介面可查詢分頁內容,以及整個視窗和裝置。舉例來說,resizeTo()
方法可用來調整瀏覽器視窗大小,devicePixelRatio
屬性可讓您存取裝置的顯示像素。存取內容所屬分頁的相關資訊時,並非分頁顯示的 DOM 樹狀結構,該視窗可能是您所尋找的介面。
有些 API 是以 Window 介面顯示的功能為基礎,包括網路工作站和 IndexedDB API。
隨堂測驗
測驗您對 HTML API 的相關知識。
DOM 中的 O 代表什麼意義?
你可以透過哪個介面查看內容所在分頁的相關資訊?