この節では、簡単かつ概念的に DOM を紹介します。それは何であり、 HTMLXML 文書にどのような構造を与え、アクセスはどのようにして可能であり、この API はどのようにして参照される情報を提供するかと、そして例を示します。

DOM とは

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

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

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

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

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

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

DOM と JavaScript

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

初期には JavaScript と DOM は強く結びついていましたが、最終的には別々の存在ととして発展しました。ページの内容は DOM に格納され、 JavaScript から操作できるでしょう。なのでこの近似の等式を書くことができるでしょう。

API (HTML または XML ページ) = DOM + JS (スクリプト言語)

DOM はいかなるプログラミング言語からも独立して作られていて、一つの一貫した API から構造的な表現を作ります。このリファレンスでは、 JavaScript に特別な焦点を当てますが、DOM の実装はいかなる言語でもできます。ここに、 Python の例を挙げます。

# 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> 要素であろうとも、スクリプトを読み込む命令によってウェブページに埋め込まれていようとも、スクリプトを作れば、 documentwindow 要素といったウェブページ中のさまざまな要素に対するに API をすぐに使い始めることが出来ます。それらの API で文書自身を操作したり、文書の子要素を取り出したりできます。 DOM でのプログラミングは以下のように簡単に出来ます。1 つは、 window オブジェクトの 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
         var heading = document.createElement("h1");
         var heading_text = document.createTextNode("Big Head!");
         heading.appendChild(heading_text);
         document.body.appendChild(heading);
      }
    </script>
  </head>
  <body>
  </body>
</html>

重要なデータ型

このリファレンスでは、様々なオブジェクトと種類をなるべく簡単な方法で説明します。しかし、API に渡される、注意しなければならないデータ型はたくさんあります。簡潔さのために、この API リファレンスでの構文の例は ノードを element とし、ノードの配列を nodeList (または、単純に elements)、さらに 属性ノードを単純に attribute として参照しています。

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

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

DOM インタフェース

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

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

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

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

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

var table = document.getElementById("table");
var tableAttrs = table.attributes; // Node/Element インターフェイス
for (var 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 type="application/javascript">
    function setBodyAttr(attr, value){
      if (document.body) eval('document.body.'+attr+'="'+value+'"');
      else notSupported();
    }
    </script>
  </head> 
  <body>
    <div style="margin: .5in; height: 400;"> 
      <p><b><tt>text</tt></b></p> 
      <form> 
        <select onChange="setBodyAttr('text',
        this.options[this.selectedIndex].value);"> 
          <option value="black">black 
          <option value="darkblue">darkblue 
        </select>
        <p><b><tt>bgColor</tt></b></p>
        <select onChange="setBodyAttr('bgColor',
        this.options[this.selectedIndex].value);"> 
          <option value="white">white 
          <option value="lightgrey">gray
        </select>
        <p><b><tt>link</tt></b></p> 
        <select onChange="setBodyAttr('link',
        this.options[this.selectedIndex].value);">
          <option value="blue">blue
          <option value="green">green
        </select>  <small>
        <a href="http://some.website.tld/page.html" id="sample">
        (sample link)</a></small><br>
      </form>
      <form>
        <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 の使い方を効果的に学ぶ上で重要なことです。

ドキュメントのタグと貢献者

タグ: 
このページの貢献者: mfuji09, miyataka, arunpandianp, ethertank, Taken, Yukoba, Ktjpn, Shimono, Kaorine, Mgjbot
最終更新者: mfuji09,