HTML API

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

DOM と AOM

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

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

ブラウザツールには上記のようなツリーの可視化機能がありませんが、要素インスペクタでノードを確認できます。

DOM/ARIA。

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

AOM の例。

HTML Element API

DOM の中央の文字は「オブジェクト」です。オブジェクト指向プログラミング クラスの入門編で紹介した personcar オブジェクトの例と同様に、ドキュメント ツリー内のすべてのノードは 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 は要素から継承され、HTML 要素固有のインターフェースはすべて要素から継承されます。一部の要素固有のインターフェースは、複数の類似した要素によって実装されます。

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

命名規則は、「HTML」の後に、要素または要素のグループ(大文字のキャメルケース)が続き、その後に「要素」が続きます。ただし、要素または要素のグループ化は厳密なパターンに従っていません。このトークンをこれらを覚える必要はありません。必要なときに調べることができるよう、必ず存在を認識しておくことが重要です。

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

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

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

インターフェースのメソッド名またはプロパティ名が継承されるインターフェースと同じ場合、継承されたメソッドまたはプロパティは継承しているメソッドまたはプロパティで上書きされます。上記の alt プロパティと offsetHeight プロパティにそれぞれ imageInstance.altsectionInstance.offsetHeight を使用してアクセスしたとき、アクセスされている API をコードは識別できませんでした。

一般的に、これら 2 つの例と同様に、これは問題ではありません。そういう場合もあります。たとえば、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;
  }
};

カスタム要素の定義には、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() メソッドは、要素インターフェースのメソッドです。ドキュメントのメインの DOM ツリーとは別にレンダリングされる Shadow DOM API 用の shadowRoot インターフェースもあります。

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

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

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

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

Window インターフェース

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

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

Web WorkerIndexedDB API など、Window インターフェースを通じて表示される機能に基づいて、いくつかの API が利用できます。

理解度をチェックする

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

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

指向。
もう一度お試しください。
オブジェクト。
正解です。
外側。
もう一度お試しください。

コンテンツが表示されているタブに関する情報を確認するのに役立つインターフェースはどれですか。

ウィンドウ
正解です。
ドキュメント
もう一度お試しください。
ノード
もう一度お試しください。