Trong phần giới thiệu của loạt bài này, có nói "Phần tử HTML là các nút tạo nên Mô hình đối tượng tài liệu". Chúng ta đã thảo luận về loại nút phần tử. Trong phần này, chúng ta sẽ thảo luận về các API phần tử cho phép truy vấn các nút đó.
DOM và AOM
DOM là một API để truy cập và thao tác với tài liệu. DOM là cây của tất cả các nút trong tài liệu. Một số nút có thể chứa nút con cháu, còn một số nút khác thì không. Cây bao gồm các phần tử, cùng với các thuộc tính của các phần tử đó và các nút văn bản.
Các công cụ trình duyệt không cung cấp hình ảnh trực quan dạng cây như hình ảnh ở trên, nhưng bạn có thể thấy các nút trong trình kiểm tra phần tử.
Biểu diễn dạng cây có thể kiểm tra trong các công cụ cho nhà phát triển của trình duyệt là cây hỗ trợ tiếp cận. AOM dựa trên DOM; tương tự như vậy, cây hỗ trợ tiếp cận chứa các đối tượng đại diện cho tất cả các phần tử đánh dấu, thuộc tính và nút văn bản:
API phần tử HTML
Chữ cái ở giữa của DOM là "object". Giống như ví dụ về đối tượng person
hoặc car
từ hầu hết các lớp giới thiệu đến lớp lập trình hướng đối tượng, mỗi nút trong cây tài liệu là một đối tượng có thể bị điều khiển bằng JavaScript.
Trình duyệt cung cấp nhiều API cung cấp các phương thức, sự kiện cũng như hoạt động truy vấn và cập nhật thuộc tính được hỗ trợ sẵn.
Các nút phần tử chứa thông tin về tất cả thuộc tính được đặt trên phần tử. Bạn có thể sử dụng giao diện HTML để truy cập thông tin về các thuộc tính của một phần tử. Ví dụ: chúng ta có thể sử dụng HTMLImageElement.alt
để nhận thuộc tính alt
của mọi hình ảnh:
let allImages = document.querySelectorAll('img');
allImages.forEach((imageInstance) => {
console.log(imageInstance.alt);
});
Giao diện HTML không chỉ cung cấp quyền truy cập vào các thuộc tính của một phần tử; bạn còn có thể truy cập vào nhiều thông tin khác. Chúng ta có thể tìm thấy HTMLElement.offsetHeight
chỉ đọc để biết chiều cao của từng phần trong trang, tương ứng với bố cục.
let allSections = document.querySelectorAll('section');
allSections.forEach((sectionInstance) => {
console.log(sectionInstance.offsetHeight);
});
Nếu người dùng thay đổi hướng thiết bị hoặc thay đổi chiều rộng của khung nhìn, thì chiều cao của mỗi <section>
sẽ thay đổi và các thuộc tính DOM sẽ tự động cập nhật theo chiều cao đó.
Các API giao diện HTML không bị giới hạn ở việc truy cập vào các giá trị thuộc tính. DOM cung cấp thông tin chi tiết về trạng thái hiện tại của giao diện người dùng.
API HTML có thể truy cập tất cả thông tin đó. Bạn có thể xem thời lượng của video, vị trí khung hiển thị đang phát trong chế độ phát hiện tại và liệu video (hoặc âm thanh) đã phát xong bằng HTMLMediaElement.duration
, HTMLMediaElement.currentTime
và HTMLMediaElement.ended
hay chưa.
Các giao diện phần tử có sẵn
Hầu hết phần tử HTML mà chúng tôi đã đề cập cho đến thời điểm này trong loạt bài này và chưa trình bày, ngoại trừ một số phần tử phân mục, có giao diện DOM liên kết. Giao diện cơ sở cho tất cả các phần tử được đặt tên riêng là Element (Phần tử).
HTMLElement
kế thừa từ Phần tử và tất cả giao diện dành riêng cho phần tử HTML đều kế thừa từ đó. Một số giao diện dành riêng cho từng phần tử được triển khai bởi nhiều phần tử tương tự nhau.
Các giao diện bao gồm:
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>
Quy ước đặt tên là "HTML", theo sau là một phần tử hoặc nhóm các phần tử viết hoa kiểu lạc đà, theo sau là "Phần tử", nhưng phần tử hoặc nhóm các phần tử không tuân theo mẫu chính xác. Đừng lo. Bạn không cần phải ghi nhớ những chế độ này. Điều quan trọng là bạn cần biết rằng chúng tồn tại để bạn có thể tra cứu khi cần.
Nếu bạn có một tập hợp các phần tử, bạn cũng sẽ thấy một số giao diện tập hợp nữa. Ví dụ: phương thức HTMLCollection.namedItem()
sẽ trả về phần tử đầu tiên trong bộ sưu tập có thuộc tính id
hoặc name
khớp với tham số hoặc trả về giá trị rỗng nếu không có phần tử nào khớp.
Hơn 30 phần tử không có giao diện DOM nào khác ngoài HTMLElement
, bao gồm <address>
, <article>
, <section>
, <nav>
, <header>
, <footer>
, <aside>
và <hgroup>
. Nhiều phần tử không hỗ trợ các thuộc tính chung và không dùng nữa có các giao diện dành riêng cho phần tử, chẳng hạn như HTMLPElement
(phần tử <p>
) và HTMLUnknownElement
(<😃>
hoặc bất kỳ phần tử nào khác chưa được xác định), nhưng các giao diện đó không triển khai thêm thuộc tính hoặc phương thức nào bên trên các thuộc tính và phương thức kế thừa từ HTMLElement
, nên không được liệt kê ở trên.
Các thuộc tính và phương thức API dự phòng
Nếu một giao diện có cùng tên phương thức hoặc thuộc tính và giao diện kế thừa, thì phương thức hoặc thuộc tính kế thừa sẽ ghi đè phương thức hoặc thuộc tính kế thừa. Khi chúng ta truy cập vào các thuộc tính alt
và offsetHeight
ở trên bằng imageInstance.alt
và sectionInstance.offsetHeight
tương ứng, mã không xác định được API nào đang được truy cập.
Nói chung, như với hai ví dụ này, đây không phải là vấn đề. Nhưng điều đó có thể xảy ra. Ví dụ: HTMLCollection.length
ở chế độ chỉ có thể đọc, trong khi thuộc tính độ dài của giao diện HTMLOptionsCollection
kế thừa (chỉ được thuộc tính options
của <select>
trả về) cũng có thể được dùng để đặt kích thước bộ sưu tập.
Giao diện khác
Có các giao diện bổ sung cho phép thao túng các vị trí nhánh của nút DOM. Giao diện EventTarget
(cung cấp cho chúng tôi) addEventListener()
và removeEventListener()
được kế thừa qua các giao diện Node
và Window
. Đổi lại, các giao diện Phần tử, Tài liệu và DocumentFragment (mà chúng ta đã thấy trong phần tử tuỳ chỉnh) sẽ kế thừa từ Nút và giao diện HTMLElement kế thừa từ Phần tử.
Giao diện node
Mỗi loại nút DOM được biểu thị bằng một giao diện dựa trên Node
. Giao diện này cung cấp thông tin và phương thức dưới dạng các phần tử liên quan đến cây DOM. Giao diện Node
cho phép truy vấn và thêm nút vào cây nút.
Chức năng "hướng dẫn DOM" nổi tiếng của Douglas Crockford tận dụng các thuộc tính firstChild
và nextSibling
của Nút.
const walk_the_DOM = function walk(node, callback) {
callback(node);
node = node.firstChild;
while (node) {
walk(node, callback);
node = node.nextSibling;
}
};
Chúng tôi đã sử dụng phương thức appendChild()
và cloneNode()
của Nút để xác định phần tử tuỳ chỉnh.
Giao diện Nút cung cấp nhiều thuộc tính và phương thức hữu ích để truy vấn và thao tác với 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));
}
});
Phương thức attachShadow()
là một phương thức của giao diện Phần tử. Ngoài ra, còn có giao diện shadowRoot
cho Shadow DOM API được hiển thị riêng biệt với cây DOM chính của tài liệu.
Giao diện Document
và HTMLDocument
Giao diện Document
kế thừa từ Node
. Thuộc tính này đại diện cho trang web được tải trong trình duyệt, cho dù tài liệu là HTML, SVG, XML, MathML hay loại khác. Giao diện Document
cũng
kế thừa từ giao diện HTMLDocument
.
document
cho phép truy cập nhanh vào các loại nút và khả năng tạo tập hợp các loại phần tử cụ thể, chẳng hạn như document.body
và document.styleSheets
. HTMLDocument cho phép truy cập thông tin liên quan đến tài liệu không có trong các nút HTML, chẳng hạn như Document.location
,
Document.lastModified
và Document.Cookie
.
Một số API có sẵn dựa trên các tính năng xuất hiện trên giao diện tài liệu, trong đó có API kéo và thả và API FullScreen. Cả hai đều kế thừa từ Element
.
Giao diện Window
Giao diện Cửa sổ bao gồm các mục có sẵn trên toàn cầu ngoài DOM có thể được sử dụng để thao tác với DOM. Cửa sổ cung cấp các hàm, không gian tên, đối tượng và hàm khởi tạo được ghi lại trong JavaScript và Tài liệu tham chiếu DOM của MDN.
Giao diện Cửa sổ là API cho đối tượng chứa tài liệu. Đối tượng window
chung là cửa sổ nơi tập lệnh đang chạy. Mỗi thẻ trình duyệt chứa đối tượng Cửa sổ riêng của nó. Giao diện Cửa sổ có thể truy vấn nội dung của thẻ, cũng như cửa sổ tổng thể và thiết bị. Ví dụ: bạn có thể dùng phương thức resizeTo()
để đổi kích thước cửa sổ trình duyệt, thuộc tính devicePixelRatio
sẽ cung cấp quyền truy cập vào pixel hiển thị của thiết bị. Khi truy cập thông tin về thẻ chứa nội dung chứ không phải cây DOM mà thẻ hiển thị, cửa sổ đó có thể là giao diện bạn đang tìm kiếm.
Một số API có sẵn dựa trên các tính năng xuất hiện qua giao diện Cửa sổ, trong đó có API Web Workers và IndexedDB.
Kiểm tra kiến thức
Kiểm tra kiến thức của bạn về API HTML.
O trong DOM là gì?
Giao diện nào có thể giúp bạn tìm hiểu thông tin về thẻ chứa nội dung đó?