Trong phần giới thiệu về loạt bài này, có viết "Các 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ể có nút con, một số khác thì không. Cây này bao gồm các phần tử, cùng với các thuộc tính và 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 trên, nhưng bạn có thể thấy các nút trong trình kiểm tra phần tử.
Cây hỗ trợ tiếp cận là cách trình bày dạng cây có thể được kiểm tra trong các công cụ dành cho nhà phát triển trình duyệt. AOM dựa trên DOM; tương tự, 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" (đối tượng). Giống như ví dụ về đối tượng person
hoặc car
trong hầu hết các lớp học nhập môn về lập trình hướng đối tượng, mọi nút trong cây tài liệu đều là một đối tượng có thể được thao tác 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 và truy vấn cũng như cập nhật thuộc tính được hỗ trợ gốc.
Các nút phần tử chứa thông tin về tất cả cá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 vào 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
để lấy các thuộc tính alt
của tất cả 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ử mà 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ó thể đọc để lấy 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, 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 đó.
API giao diện HTML không chỉ 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 vào tất cả thông tin đó. Bạn có thể truy cập vào thời lượng của video, vị trí của một lượt xem trong quá trình phát hiện tại, và liệu video (hoặc âm thanh) đã phát xong hay chưa bằng HTMLMediaElement.duration
, HTMLMediaElement.currentTime
và HTMLMediaElement.ended
tương ứng.
Các giao diện phần tử có sẵn
Hầu hết các phần tử HTML mà chúng ta đã đề cập đến trong loạt bài này và chưa đề cập đến, ngoài một số phần tử phân đoạn, đều 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 một cách thích hợp 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 kế thừa từ phần tử này. Một số giao diện dành riêng cho phần tử được triển khai bằng nhiều phần tử tương tự.
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 phần tử viết hoa kiểu camel, theo sau là "Phần tử", nhưng phần tử hoặc nhóm 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 điều này. Điều quan trọng là bạn phải biết rằng các tệp này 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ử, thì cũng có một số giao diện tập hợp. Ví dụ: phương thức HTMLCollection.namedItem()
trả về phần tử đầu tiên trong tập hợp có thuộc tính id
hoặc name
khớp với tham số hoặc 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 được liên kết ngoài HTMLElement
, bao gồm <address>
, <article>
, <section>
, <nav>
, <header>
, <footer>
, <aside>
và <hgroup>
. Nhiều phần tử không hỗ trợ bất kỳ thuộc tính nào không còn được dùng nữa, không phải thuộc tính toàn 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 không được xác định), nhưng các giao diện đó không triển khai bất kỳ thuộc tính hoặc phương thức bổ sung nào ngoài các thuộc tính và phương thức kế thừa từ HTMLElement
và không được liệt kê ở trên.
Các phương thức và thuộc tính API thừa
Nếu một giao diện có cùng tên phương thức hoặc thuộc tính với giao diện mà 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 được kế thừa. Nói cách khác, các phương thức và thuộc tính mẹ sẽ ghi đè các phương thức và thuộc tính con. Khi chúng ta truy cập vào các thuộc tính alt
và offsetHeight
trong API Phần tử HTML với 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 đề.
Tuy nhiên, có một số trường hợp dư thừa có thể gây ra sự cố. Ví dụ: HTMLCollection.length
chỉ có thể đọc, trong khi giao diện kế thừa HTMLOptionsCollection
có thuộc tính độ dài (chỉ được trả về bởi thuộc tính options
của <select>
) với quyền đọc và ghi. Bạn có thể dùng HTMLOptionsCollection
để đặt kích thước bộ sưu tập.
Các giao diện khác
Có các giao diện bổ sung cho phép thao tác với vị trí nhánh của các nút DOM. Giao diện EventTarget
cung cấp cho chúng ta addEventListener()
và removeEventListener()
, được kế thừa bởi các giao diện Node
và Window
. Đổi lại, giao diện Element, Document và DocumentFragment (mà chúng ta đã thấy trong thành phần tuỳ chỉnh) kế thừa từ Node và giao diện HTMLElement kế thừa từ Element.
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.
Hàm "đi qua DOM" nổi tiếng của Douglas Crockford sử dụng các thuộc tính firstChild
và nextSibling
của Node.
const walk_the_DOM = function walk(node, callback) {
callback(node);
node = node.firstChild;
while (node) {
walk(node, callback);
node = node.nextSibling;
}
};
Chúng ta đã sử dụng các phương thức appendChild()
và cloneNode()
của Node để xác định các 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 Element. 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
.
Có một số API dựa trên các tính năng xuất hiện thông qua giao diện tài liệu, bao gồm API Kéo và thả và API Toàn màn hình. Cả hai đều kế thừa từ Element
.
Giao diện Window
Giao diện Window bao gồm các mục có sẵn trên toàn cầu ngoài DOM có thể dùng để thao tác với DOM. Window 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à Tham chiếu DOM của MDN.
Giao diện Window là API cho đối tượng chứa tài liệu. Đối tượng window
toàn cục là cửa sổ mà tập lệnh đang chạy. Mỗi thẻ trình duyệt đều chứa đối tượng Window riêng. Giao diện Cửa sổ có thể truy vấn nội dung của thẻ cũng như cửa sổ và thiết bị tổng thể. Ví dụ: bạn có thể sử dụng phương thức resizeTo()
để đổi kích thước cửa sổ trình duyệt, thuộc tính devicePixelRatio
cung cấp quyền truy cập vào các pixel hiển thị của thiết bị. Khi truy cập thông tin về thẻ chứa nội dung thay vì cây DOM mà thẻ hiển thị, cửa sổ có thể là giao diện mà bạn đang tìm kiếm.
Có một số API dựa trên các tính năng xuất hiện thông qua giao diện Cửa sổ, bao gồm cả API Web Worker và IndexedDB.
Kiểm tra mức độ hiểu biết
Kiểm tra kiến thức của bạn về API HTML.
O trong DOM có nghĩa 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?