API HTML

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ây nút MLW hiển thị các phần tử 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 ảnh ở trên, nhưng bạn có thể thấy các nút trong trình kiểm tra phần tử.

DOM/ARIA.

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:

Ví dụ về AOM.

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.currentTimeHTMLMediaElement.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:

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><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 altoffsetHeight ở trên bằng imageInstance.altsectionInstance.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()removeEventListener() được kế thừa qua các giao diện NodeWindow. Đổ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 firstChildnextSibling 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()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 DocumentHTMLDocument

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.bodydocument.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.lastModifiedDocument.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ả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 JavaScriptTà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 WorkersIndexedDB.

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ì?

Đã định hướng.
Hãy thử lại.
Đối tượng.
Chính xác!
Bên ngoài.
Hãy thử lại.

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 đó?

Cửa sổ
Chính xác!
Tài liệu
Hãy thử lại.
Nút
Hãy thử lại.