--- title: DOM の紹介 slug: Web/API/Document_Object_Model/Introduction tags: - Beginner - DOM - Document - Guide - HTML DOM - Introduction - Tutorial - 導入 translation_of: Web/API/Document_Object_Model/Introduction ---

Document Object Model (DOM) は、ウェブ上の文書のコンテンツと構造からなるオブジェクトのデータ表現です。このガイドでは、簡単に DOM を紹介します。 DOM がどのようにメモリ内で {{Glossary("HTML")}} または {{Glossary("XML")}} の文書を表現するか、どのように API を使用してウェブコンテンツやアプリケーションを作成するのかを見てみます。

DOM とは

Document Object Model (DOM) は HTML や XML 文書のためのプログラミングインターフェイスです。ページを表現するため、プログラムが文書構造、スタイル、内容を変更することができます。 DOM は文書をノードとオブジェクトで表現します。そうやって、プログラミング言語をページに接続することができます。

ウェブページは文書です。この文書はブラウザーのウィンドウに表示されるか HTML ソースとして表示することが可能です。しかし両方の場合においてもそれは同じ文書です。ドキュメントオブジェクトモデル (DOM) は、その同じ文書を表現、保存、操作する方法です。DOM はウェブページの完全なオブジェクト指向の表現で、 JavaScript のようなスクリプト言語から変更できます。

W3C DOM および WHATWG DOM 標準は、現代のブラウザーのほとんどで実装されています。多くのブラウザーは標準を拡張しているので、文書が様々なブラウザーの異なる DOM からアクセスされるウェブにおいては注意が必要です。

例えば、標準 DOM は以下のコードにおける getElementsByTagName メソッドが文書内のすべての <p> 要素のリストを返さなければならないと定義しています。

const paragraphs = document.getElementsByTagName("p");
// paragraphs[0] は最初の <p> 要素
// paragraphs[1] は 2 番目の <p> 要素...
alert(paragraphs[0].nodeName);

ウェブページを操作したり、作成したりするために用意されているすべてのプロパティ、メソッド、イベントは、オブジェクトにまとめられています (例えば、文書自身を表現する document オブジェクトや、 HTML のテーブルにアクセスするための特別な {{domxref("HTMLTableElement")}} DOM インターフェイスを実装した table オブジェクト、などなど)。この文書では DOM について、オブジェクトごとのリファレンスを提供します。

現在の DOM は協調して動作する複数 API によって構築されています。コア DOM は、文書やその中のオブジェクトを基礎的に記述するオブジェクトを定義しています。これは必要に応じて DOM に新しい機能や能力を追加する他の API によって拡張されます。例えば、 HTML DOM API はコア DOM に HTML 文書の表現の対応を追加しています。

DOM と JavaScript

このリファレンスでの例と同様に、上の短い例は {{glossary("JavaScript")}} で書かれています。つまり、 JavaScript で書かれていますが、しかし DOM を使用してウェブページとその要素にアクセスしています。 DOM はプログラミング言語ではありませんが、これがないと、 JavaScript 言語はウェブページ、 HTML 文書、 XML 文書、およびその構成部品 (要素など) のモデルや記法を持っていません。文書内のすべての要素 — 全体としての文書、 head、文書内の表、表の見出し、表のセル内のテキスト — は、その文書のドキュメントオブジェクトモデルの一部ですので、 DOM と JavaScript のようなスクリプト言語を通してそれらすべてにアクセスし、操作することができます。

当初、 JavaScript と DOM は密接に絡み合っていましたが、最終的には別々の存在に進化しました。ページの内容は DOM に格納されており、 JavaScript を介してアクセスしたり操作したりすることができるので、この近似式を書くことができます。

API = DOM + JavaScript

DOM は特定のプログラミング言語に依存しないように設計されており、文書の構造表現を単一の一貫した API から利用できるようになっています。このリファレンス文書では JavaScript のみに焦点を当てていますが、この Python の例が示すように、DOM の実装はどのような言語にも対応できるようになっています。

# Python DOM example
import xml.dom.minidom as m
doc = m.parse(r"C:\Projects\Py\chap1.xml")
doc.nodeName # DOM property of document object
p_list = doc.getElementsByTagName("para")

ウェブで JavaScript を書くためにどのような技術が使われるのかについての詳細は、 JavaScript 技術概要をご覧ください。

DOM へのアクセス

DOM を使い始めるには、何も特別なものは必要ありません。異なるブラウザーは異なる DOM の実装をもっています。そして、これらの実装の実際の DOM の規格への適応度はさまざまです (この話題に関してはこの文書では避けます)。しかし、すべてのウェブラウザーはスクリプトからウェブページにアクセスできるように何らかのドキュメントオブジェクトモデルを持っています。

インラインの <script> 要素であろうとも、スクリプトを読み込む命令によってウェブページに埋め込まれていようとも、スクリプトを作れば、 {{domxref("document")}} や {{domxref("Window", "window")}} 要素といったウェブページ中のさまざまな要素に対するに API をすぐに使い始めることが出来ます。それらの API で文書自身を操作したり、文書の子要素を取り出したりできます。 DOM でのプログラミングは以下のように簡単に出来ます。1 つは、 {{domxref("Window", "window")}} オブジェクトの {{domxref("Window.alert", "alert()")}} 関数を利用し、警告メッセージを表示しています。より長い例はより洗練された DOM 関数を使い、実際に新しいコンテンツを作り出しています。

以下の JavaScript は、文書が読み込まれた時 (として DOM が利用可能になった時) にアラートを表示します。

<body onload="window.alert('私のホームページへようこそ!');">

他の例です。この関数は新しい H1 要素を作成し、その要素にテキストを加え、文書のツリーに H1 要素を加えています。

<html>
  <head>
    <script>
       // この関数は文書が読みこまれた時に実行される
       window.onload = function() {

         // create a couple of elements in an otherwise empty HTML page
         const heading = document.createElement("h1");
         const heading_text = document.createTextNode("Big Head!");
         heading.appendChild(heading_text);
         document.body.appendChild(heading);
      }
    </script>
  </head>
  <body>
  </body>
</html>

基本的なデータ型

このリファレンスでは、様々なオブジェクトと種類をなるべく簡単な方法で説明します。しかし、API に渡される、注意しなければならないデータ型はたくさんあります。

注: DOM を使用するコードの大部分は HTML 文書の操作を中心としているため、DOM 内のノードを要素と呼ぶのが一般的ですが、厳密にはすべてのノードが要素というわけではありません。

以下の表はこれらのデータの種類を簡単に説明しています。

データ型 (インターフェイス) 説明
{{domxref("Document")}} メンバーが document 型のオブジェクトを返すときは (例えば、element の ownerDocument 属性はそれが属する document を返します)、このオブジェクトはルートの document オブジェクト自身です。DOM の document リファレンスの章は document オブジェクトを説明しています。
{{domxref("Node")}} 文書内にあるすべてのオブジェクトは何らかの種類のノードです。 HTML 文書では、オブジェクトは要素ノードだけでなく、テキストノードや属性ノードもあります。
{{domxref("Element")}} element 型は node に基づいています。これは要素、または DOM API のメンバーから返される element 型のノードのことです。例えば、 {{domxref("document.createElement()")}} メソッドは node へのオブジェクト参照を返すというより、このメソッドは単に DOM によって生成された element を返すと言えます。 element オブジェクトは DOM の Element インターフェイスと、もっと基本的な Node インターフェイスも実装しており、両方がこの参照に含まれます。 HTML 文書では、要素はさらに HTML DOM API の {{domxref("HTMLElement")}} インターフェイスや、特定の種類の要素における能力を記述するためのその他のインターフェイス (例えば {{HTMLElement("table")}} 要素における {{domxref("HTMLTableElement")}}) によって更に拡張されています。
{{domxref("NodeList")}} nodeList は、 {{domxref("document.getElementsByTagName()")}} で返されるものなど要素の配列です。 nodeList 中の項目は、インデックスを使って以下の2つの方法で取得できます。
  • list.item(1)
  • list[1]
この二つの方法は等価です。最初の方法では、 item()nodeList オブジェクトの一つの関数です。後者の方は、一般的な配列の構文を使い、リスト中の二つ目の項目を取得しています。
{{domxref("Attribute")}} attribute が (createAttribute() メソッドなどの) メンバーから返されたとき、属性のための特別な (ただし、小さな) インターフェイスを実装したオブジェクトの参照です。属性は要素のような DOM のノードですが、さほど使われません。
{{domxref("NamedNodeMap")}} namedNodeMap は配列のようですが、名前またはインデックスによって項目にアクセスきますが、後者は項目がリスト中に特定の順番で並んでいる訳ではないので、列挙するのに便利であるだけです。このために namedNodeMap には item() メソッドがあり、 namedNodeMap に項目を追加したり、削除したりすることができます。

注意すべき用語の使い方がいくつかあります。例えば、ある {{domxref("Attribute")}} ノードを参照するのに単に attribute と呼んだり、 DOM ノードの配列を参照するのに nodeList と呼んだりします。このような用語は文書を通して紹介され使用されているのが分かるでしょう。

DOM インタフェース

このガイドは、 DOM 階層構造を操作するために利用できるオブジェクトと、実際のものについて触れます。どのように動作するかを理解する上で、混乱を催すかもしれない点がたくさんあります。例えば、 HTML の form 要素を表すオブジェクトには、 name プロパティが HTMLFormElement インターフェイスにある一方、 className プロパティが HTMLElement インターフェイスにあります。どちらにしても、求めるプロパティはその form オブジェクトの中にあります。

しかし、 DOM で実装されているオブジェクトとインターフェイスの関係は複雑なので、この節では、 DOM の仕様での実際のインターフェイスとそれがどのように利用できるかについて少し説明しようと思います。

インターフェイスとオブジェクト

多くのオブジェクトは複数のインターフェイスを受けついでいます。例えば、 table オブジェクトでは、特別な {{domxref("HTMLTableElement")}} インターフェイスを実装しており、そのインターフェイスは createCaptioninsertRow などのメソッドを含んでいます。しかし、 table は HTML の要素でもあるので、 DOM の {{domxref("Element")}} リファレンスの章で説明している Element インターフェイスも実装しています。さらには、 HTML の要素は、 DOM を考慮する限り、ウェブページや XML ページのオブジェクトモデルを作りあげるノードのツリー内にあるノードもであるので、 table オブジェクトはより基本的な Node インターフェイスを、 Element から継承して実装しています。

次の例のように、 table オブジェクトの参照を入手したときは、おそらく無意識に、このオブジェクトの三つのインターフェイスをごく普通に交互に使います。

const table = document.getElementById("table");
const tableAttrs = table.attributes; // Node/Element インターフェイス
for (let i = 0; i < tableAttrs.length; i++) {
  // HTMLTableElement インターフェイス: border 属性
  if(tableAttrs[i].nodeName.toLowerCase() == "border")
    table.border = "1";
}
// HTMLTableElement インターフェイス: summary 属性
table.summary = "注意: 太くなった枠線";

DOM の中で核となるインターフェイス

この節では、 DOM の中で最もよく使われるインターフェイスを列挙します。API がここで何をしているか記述するのではなく、DOM の中で非常に良く使われる関数や属性をちょっと示すのが狙いです。これらよく使われる API はこの本の最後の DOM の例の章のより長い例の中で使われています。

documentwindow オブジェクトが一般的に DOM プログラミングの中で最もよく使われます。簡単に言うと、 window オブジェクトはブラウザーのようなものを表現し、 document オブジェクトは文書のルート自身です。 Element は一般的な Node インターフェイスを継承していて、あわせてこの 2 つのインターフェイスはここの要素で使われる多くの関数と属性を提供します。前節での table オブジェクトの例のように、これの要素はそれぞれが持つデータを扱うための特定のインターフェイスを持っている場合があります。

以下は、 DOM を使うウェブや XML ページのスクリプトでよく使われる API の簡単な一覧です。

DOM API のテスト

この文書は、ウェブ開発に利用できるあらゆるインターフェイスの例を提供しています。いくつかの場合では、サンプルは完全な HTML ページで、これは DOM アクセスは <script> 要素の中に入っており、フォームのスクリプトを起動するのに必要なインターフェイス (例えば、ボタン) があり、DOM が操作する HTML 要素がリストされています。この場合は、例を新しい HTML 文書にカット・アンド・ペーストし、保存し、ブラウザーから例を走らせることができます。

しかし、いくつかのケースでは例はより簡潔です。HTML 要素のインターフェイスの基本的な関係を示すだけの例を走らせるために、インターフェイスがスクリプトから簡単にアクセスできるようなテストページを準備したいと思うかもしれません。以下の非常に簡単なウェブページはインターフェイスをテストする関数をおけるようにするヘッダー中の <script> 要素と、習得・設定・操作できる属性を持ったいくつかの HTML 要素と、ブラウザーからこれらの関数を呼ぶのに必要なウェブのユーザーインターフェイスを提供しています。

あなたが興味のある DOM インターフェイスをテストするために、このテストページや似たようなものを作ることができますし、ブラウザー上でどのように動くか見れます。必要であれば test() 関数の中身を更新したり、もっとボタンを作ったり、必要な要素を追加したりできます。

<html>
<head>
  <title>DOM Tests</title>
  <script>
    function setBodyAttr(attr, value) {
      if (document.body) document.body[attr] = value;
      else throw new Error("no support");
    }
  </script>
</head>
<body>
  <div style="margin: .5in; height: 400px;">
    <p><b><tt>text</tt></b></p>
    <form>
      <select onChange="setBodyAttr('text',
        this.options[this.selectedIndex].value);">
        <option value="black">black</option>
        <option value="red">red</option>
      </select>
      <p><b><tt>bgColor</tt></b></p>
      <select onChange="setBodyAttr('bgColor',
        this.options[this.selectedIndex].value);">
        <option value="white">white</option>
        <option value="lightgrey">gray</option>
      </select>
      <p><b><tt>link</tt></b></p>
      <select onChange="setBodyAttr('link',
        this.options[this.selectedIndex].value);">
        <option value="blue">blue</option>
        <option value="green">green</option>
      </select>
      <small>
        <a href="http://some.website.tld/page.html" id="sample">
          (sample link)
        </a>
      </small><br />
      <input type="button" value="version" onclick="ver()" />
    </form>
  </div>
</body>
</html>

例えば、ウェブページの色に影響する一連の属性のように、たくさんのインターフェイスを一つのページでテストするために、ボタンやテキスト入力欄、その他の HTML 要素を全部集めた似たようなテストページを作ることができます。以下のスクリーンショットは、インターフェイスをテストのために一緒にまとめる方法のアイディアを示します。

図 0.1 DOM テストページの例
画像:DOM_Ref_Introduction_to_the_DOM.gif

この例では、ウェブページの DOM からアクセス可能であるという側面から、ドロップダウンメニューの背景色 (bgColor) やハイパーリンクの色 (aLink) や文字色 (text) を動的に更新します。しかし、読んだことについてインターフェイスをテストするテストページを設計してみることは、 DOM の使い方を効果的に学ぶ上で重要なことです。

{{DefaultAPISidebar("DOM")}}