HTML API

このシリーズの冒頭で、「HTML 要素は ドキュメント オブジェクト モデルを構成するノードである」と説明しました。要素ノードのタイプについて説明しました。このセクションでは、これらのノードのクエリを可能にする要素 API について説明します。

DOM と AOM

DOM は、ドキュメントにアクセスして操作するための API です。DOM は、ドキュメント内のすべてのノードのツリーです。ノードによっては子を持つことができ、そうでないノードもあります。ツリーには、要素とその属性、テキストノードが含まれます。

要素とテキストノードを示す MLW ノードツリー。

ブラウザ ツールでは、上記のようなツリー可視化は提供されていませんが、要素インスペクタでノードを確認できます。

DOM/ARIA。

ブラウザのデベロッパー ツールで検査できるツリー表現は、ユーザー補助ツリーです。AOM は DOM に基づいています。同様に、ユーザー補助ツリーには、すべてのマークアップ要素、属性、テキストノードを表すオブジェクトが含まれています。

AOM の例。

HTML Element 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.durationHTMLMediaElement.currentTimeHTMLMediaElement.ended で確認できます。

使用可能な要素インターフェース

このシリーズでこれまで説明してきた HTML 要素のほとんどと、まだ説明していない要素(一部のセクション要素を除く)には、関連する DOM インターフェースがあります。すべての要素のベース インターフェースの名前は、適切に Element です。HTMLElement は Element から継承し、すべての HTML 要素固有のインターフェースがこれを継承します。要素固有のインターフェースは、複数の類似要素によって実装される場合があります。

インターフェースには次のようなものがあります。

命名規則は「HTML」に続いて、要素または要素のグループ化を大文字のキャメルケースで指定し、最後に「要素」を指定します。ただし、要素または要素のグループ化の部分は、厳密なパターンに従っていません。しばらく時間をおいてこれらを覚える必要はありません。必要なときに確認できるように、存在することを知っておく必要があります。

要素のコレクションがある場合は、コレクション インターフェースもあります。たとえば、HTMLCollection.namedItem() メソッドは、id 属性または name 属性がパラメータと一致するコレクション内の最初の要素を返します。一致する要素がない場合、null を返します。

30 を超える要素には、HTMLElement 以外の DOM インターフェースが関連付けられていません(<address><article><section><nav><header><footer><aside><hgroup> など)。非推奨ではないがグローバルではない属性をサポートしていない要素の多くには、HTMLPElement<p> 要素)や HTMLUnknownElement<😃> または定義されていない他の要素)などの要素固有のインターフェースがありますが、これらのインターフェースは HTMLElement から継承されたプロパティとメソッドの上に追加のプロパティやメソッドを実装しておらず、上記に記載されていません。

冗長な API メソッドとプロパティ

インターフェースに、継承するインターフェースと同じメソッド名またはプロパティ名が含まれている場合、継承元のメソッドまたはプロパティが上書きされます。つまり、親のメソッドとプロパティは子をオーバーライドします。HTML 要素 APIalt プロパティと offsetHeight プロパティにそれぞれ imageInstance.altsectionInstance.offsetHeight でアクセスしたとき、コードはどの API にアクセスしているかを特定しませんでした。通常、これらの 2 つの例と同様に、これは問題ではありません。

ただし、冗長性が問題になる場合もあります。たとえば、HTMLCollection.length は読み取り専用ですが、継承インターフェース HTMLOptionsCollection には、読み取り / 書き込みアクセス権を持つ長さプロパティ(<select>options プロパティによってのみ返される)があります。HTMLOptionsCollection を使用して、コレクション サイズを設定できます。

その他のインターフェース

DOM ノードのブランチ位置を操作できる追加のインターフェースもあります。addEventListener()removeEventListener() を提供する EventTarget インターフェースは、Node インターフェースと Window インターフェースに継承されます。一方、Element、Document、DocumentFragment(カスタム要素で説明しました)のインターフェースは Node から継承され、HTMLElement インターフェースは Element から継承されます。

node インターフェース

すべてのタイプの DOM ノードは、Node に基づくインターフェースで表されます。このインターフェースは、DOM ツリーに関連する要素として情報とメソッドを提供します。Node インターフェースを使用すると、ノードのクエリとノードのツリーへのノードの追加が可能になります。

Douglas Crockford の有名な「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 インターフェースのメソッドです。また、ドキュメントのメイン DOM ツリーとは別にレンダリングされる Shadow DOM APIshadowRoot インターフェースもあります。

Document インターフェースと HTMLDocument インターフェース

Document インターフェースは Node から継承します。ドキュメントが HTML、SVG、XML、MathML など、ブラウザに読み込まれたウェブページを表します。Document インターフェースは HTMLDocument インターフェースも継承します。

document を使用すると、ノードタイプにすばやくアクセスし、document.bodydocument.styleSheets などの特定の要素タイプのコレクションを作成できます。HTMLDocument を使用すると、HTML ノードには存在しないドキュメントに関連する情報(Document.locationDocument.lastModifiedDocument.Cookie など)にアクセスできます。

ドキュメント インターフェースで表示される機能に基づいて、Drag and Drop APIFullScreen API など、いくつかの API を使用できます。どちらも Element から継承しています。

Window インターフェース

Window インターフェースには、DOM の操作に使用できる DOM 以外のグローバルに利用可能なアイテムが含まれています。Window には、MDN の JavaScriptDOM リファレンスに記載されている関数、名前空間、オブジェクト、コンストラクタが用意されています。

Window インターフェースは、ドキュメントを含むオブジェクトの API です。グローバル window オブジェクトは、スクリプトが実行されているウィンドウです。すべてのブラウザタブには独自の Window オブジェクトが含まれています。Window インターフェースでは、タブのコンテンツだけでなく、ウィンドウとデバイス全体をクエリできます。たとえば、resizeTo() メソッドを使用してブラウザ ウィンドウのサイズを変更できます。devicePixelRatio プロパティを使用すると、デバイスのディスプレイ ピクセルにアクセスできます。タブに表示されている DOM ツリーではなく、コンテンツが含まれているタブに関する情報にアクセスする場合は、ウィンドウが目的のインターフェースである可能性があります。

Window インターフェースで公開される機能に基づいて、Web Workers API や IndexedDB API など、いくつかの API を使用できます。

理解度を確認する

HTML API に関する知識をテストします。

DOM の O は何を表していますか。

オブジェクト
外部。
向きが決まっている。

コンテンツが含まれているタブに関する情報を確認するには、どのインターフェースを使用すればよいですか。

ウィンドウ
ノード
ドキュメント