この節では、簡単かつ概念的に DOM を紹介します。それは何であり、HTML や XML 文書にどのような構造を与え、アクセスはどのようにして可能であり、この API はどのようにして参照される情報を提供するかと、そして例を示します。
DOM とはなにか?
Document Object Model (DOM) は HTML や XML 文書のためのプログラミング・インターフェースです。そして文書の構造化された表現を提供し、 プログラムから文書の構造やスタイル、コンテントを変更するためにその構造にアクセスする方法を定義します。DOM は文書の、ノードとオブジェクト (これらはさらにメソッドとプロパティをもちます) からなる構造的な集りとしての表現を提供します。ようするに、DOM は Web ページとスクリプトやプログラミング言語をつなぎます。
Web ページは文書です。この文書はブラウザのウィンドウに表示されるか HTML ソースとして表示することが可能です。しかし両方の場合においてもそれは同じ文書です。ドキュメント・オブジェクト・モデル (DOM) はその同じ文書を表現、保存、操作する方法です。DOM は Web ページの完全なオブジェクト指向の表現で、JavaScript のようなスクリプト言語から変更できます。
W3C DOM 標準はほとんどのモダンなブラウザで実装されている DOM の基本をなすものです。多くのブラウザは W3C 標準以上の独自拡張を提供しており、文書が多くのブラウザの異る DOM によってアクセスされる Web で独自拡張を使う場合には注意が必要です。
例えば W3C DOM は以下のコードにおける getElementsByTagName
メソッドは文書内のすべての <p> 要素のリストを返さなければならないと定義しています。
paragraphs = document.getElementsByTagName("P"); // paragraphs[0] は最初の <p> 要素 // paragraphs[1] は 2 番目の <p> 要素... alert(paragraphs[0].nodeName);
Web ページを操作したり、作成したりするために用意されているすべての属性、関数、イベントはオブジェクトとして提供されます (例えば、ドキュメント自身を表現する document
オブジェクトや、 HTML のテーブルにアクセスするための特別な HTMLTableElement
DOM インターフェイスを実装した table
オブジェクト、などなど)。この文書は Gecko ベースのブラウザで実装されている DOM について、オブジェクトごとのリファレンスを提供します。
DOM と JavaScript
このリファレンスでの例と同様に、上の小さな例は JavaScript で書かれています。つまり、JavaScriptで書かれていますが、しかし DOM を 利用 してウェブページとその要素にアクセスしています。DOM はプログラミング言語ではありません。しかし、DOM なしでは、JavaScript 言語は、 Web ページや XML ページ、主要な関心事項となる要素のモデルや概念を持ちません。 ドキュメント内のすべての要素—ドキュメント全体、HEAD、ドキュメント内のテーブル、テーブルのヘッダー、テーブルセル中のテキスト—はそのドキュメントのドキュメント・オブジェクト・モデルの一部であり、それゆえ DOM と JavaScript のようなスクリプト言語を通してそれらすべてにアクセスし、操作できます。
初期には JavaScript と DOM は強く結びついていましたが、最終的には別々の存在ととして発展しました。ページのコンテントは DOM に格納され、JavaScript から操作できるでしょう。なのでこの近似の等式を書くことができるでしょう。
API (web ないし XML ページ) = DOM + JS (スクリプト言語)
DOM はいかなるプログラミング言語からも独立して作られていて、一つの一貫した API から構造的な表現を作ります。このリファレンスでは、JavaScript に特別な焦点を当てますが、DOM の実装はいかなる言語でもできます。ここに、Python の例を挙げます。
# Python DOM example import xml.dom.minidom as m doc = m.parse("C:\\Projects\\Py\\chap1.xml"); doc.nodeName # DOM property of document object; p_list = doc.getElementsByTagName("para");
DOM にアクセスする方法
DOM を使い始めるには、何も特別なものは必要ありません。異なるブラウザは異なる DOM の実装をもっています。そして、これらの実装の実際の DOM の規格への適応度はさまざまです (この話題に関してはこの文書では避けます)。しかし、すべての web ブラウザはスクリプトから web ページにアクセスできるように何らかのドキュメント・オブジェクト・モデルを持っています。
インラインの <script>
要素であろうとも、スクリプトを読み込む命令によって web ページに埋め込まれていようとも、スクリプトを作れば、document
や window
要素といった Web ページ中のさまざまな要素に対するに API をすぐに使い始めることが出来ます。それらの API でドキュメント自身を操作したり、ドキュメントの子要素を取り出したりできます。DOM でのプログラミングは以下のように簡単に出来ます。1 つは、window
オブジェクトの alert()
関数を利用し、警告メッセージを表示しています。より長い例はより洗練された DOM 関数を使い、実際に新しいコンテンツを作り出しています。
<body onload="window.alert('私のホームページへようこそ!');">
JavaScript が定義されている <script>
要素のほかに、この JavaScript は新しい H1
要素を作り、その要素にテキストを加え、文書のツリーに H1
要素を加えています。
<html> <head> <script> // この関数は文書が読みこまれた時に実行される window.onload = function() { // create a couple of elements // in an otherwise empty HTML page heading = document.createElement("h1"); 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 Reference の章は document オブジェクトを説明しています。 |
element |
element は要素、つまり DOM API のメンバ変数によって返される element 型のノードのことです。例えば、document.createElement() 関数はノードへのオブジェクトの参照を返すというより、むしろ単純に、この関数は DOM によってちょうど作られたばかりの element を返すと言います。 DOM の Element インターフェイスを実装した element オブジェクトとより基本の Node インターフェイスはこのリファレンスでは一緒にして含まれています。 |
nodeList |
nodelist とは、document.getElementsByTagName() などで返される要素の配列です。 nodeList 中の項目はインデックスを使って以下の2つの方法で収得できます。
この 2 つの方法は等しいです。最初の方法では、 |
attribute |
attribute がメンバ変数によって返されるときは(例えば、createAttribute() 関数など)、属性のための特別な(ただし、小さな)インタフェイスを実装したオブジェクトの参照を返します。属性は要素のように DOM 中のノードですが、要素ほどは使われません。 |
namedNodeMap |
namedNodeMap は配列のようですが、名前とインデックスによって項目にアクセスされます。リストの中で特定の順序では並んでいないので、インデックスでアクセスするのはあまり便利な方法ではありません。この目的のために、namedNodeMap は item() 関数を用意しており、namedNodeMap から項目を追加・削除できます。 |
DOM インタフェース
このガイドの目的は、DOM の階層構造を操作できるように、オブジェクトと実際のものについて説明することです。HTML FORM
要素をあらわすオブジェクトから name
属性を HTMLFormElement
を通して取得することと、className
属性を HTMLElement
から取得することにはたいてい差がありません。両方のケースともあなたの欲しい属性は単純に form
オブジェクトの中にあります。
しかし、DOM で実装されているオブジェクトとインターフェイスの関係は複雑なので、ここの節では、DOM の仕様での実際のインターフェイスとそれがどのように利用できるかについて少し説明しようと思います。
インターフェイスとオブジェクト
多くのオブジェクトは複数のインターフェイスを受けついでいます。例えば、table オブジェクトでは、特別な HTML Table Element インターフェースを実装しており、そのインターフェイスは createCaption
や insertRow
といった関数を含んでいます。しかし、HTML の要素でもあるので、DOM element
Reference の章で説明している、Element
インターフェイスも実装しています。さらには、HTML の要素は、DOM である限り、Web ページや XML ページのオブジェクトモデルを作りあげるノードツリーのノードであるので、table 要素は、Element
が継承している、より基本的な Node
インターフェイスを実装しています。
次の例のように table
オブジェクトの参照を入手したときは、知ることなく、このオブジェクトのこれら 3 つのインターフェイスをごく普通に交互に使います。
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 の例 の章のより長い例の中で使われています。
Document
と window
オブジェクトが一般的に DOM プログラミングの中で最もよく使われます。簡単に言うと、window
オブジェクトはブラウザのようなものを表現し、document
オブジェクトはドキュメントのルート自身です。Element
は一般的な Node
インターフェイスを継承していて、あわせてこの 2 つのインターフェイスはここの要素で使われる多くの関数と属性を提供します。前節での table
オブジェクトの例のように、これの要素はそれぞれが持つデータを扱うための特定のインターフェイスを持っている場合があります。
以下は、DOM を使うウェブや XML ページのスクリプトでよく使われる API の簡単な一覧です。
document.getElementById(id)
element.getElementsByTagName(name)
document.createElement(name)
parentNode.appendChild(node)
element.innerHTML
element.style.left
element.setAttribute
element.getAttribute
element.addEventListener
window.content
window.onload
window.dump
window.scrollTo
DOM API のテスト
この文書は全てのインターフェースであなたの Web 開発において使えるにサンプルを提供しています。いくつかのケースでは、サンプルは完全な HTML ページで、これは DOM アクセスは <script> 要素の中に入っており、フォームのスクリプトを起動するのに必要なインターフェイス (例えば、ボタン) があり、DOM が操作する HTML 要素がリストされています。この場合は、例を新しい HTML ドキュメントにカット・アンド・ペーストし、保存し、ブラウザから例を走らせることができます。
しかし、いくつかのケースでは例はより簡潔です。HTML 要素のインターフェイスの基本的な関係を示すだけの例を走らせるために、インターフェイスがスクリプトから簡単にアクセスできるようなテストページを準備したいと思うかもしれません。以下の非常に簡単な Web ページはインターフェイスをテストする関数をおけるようにするヘッダー中の <script> 要素と、習得・設定・操作できる属性を持ったいくつかの HTML 要素と、ブラウザからこれらの関数を呼ぶのに必要なウェブのユーザーインターフェイスを提供しています。
あなたが興味のある DOM インターフェイスをテストするために、このテストページや似たようなものを作ることができますし、ブラウザ上でどのように動くか見れます。必要であれば test()
関数の中身を更新したり、もっとボタンを作ったり、必要な要素を追加したりできます。
<html> <head> <title>DOM Tests</title> <script type="application/x-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> color</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></p> <select onChange="setBodyAttr('bgColor', this.options[this.selectedIndex].value);"> <option value="white">white <option value="lightgrey">gray </select> <p><b><tt>link</tt></p> <select onChange="setBodyAttr('link', this.options[this.selectedIndex].value);"> <option value="blue">blue <option value="green">green </select> <small> <a href="https://www.brownhen.com/dom_api_top.html" id="sample"> (sample link)</a></small><br> </form> <form> <input type="button" value="version" onclick="ver()" /> </form> </div> </body> </html>
例えば、Web ページの色に影響する一連の属性のように、たくさんのインターフェイスを一つのページでテストするために、ボタンやテキスト入力欄、その他の HTML 要素を全部集めた似たようなテストページを作ることができます。以下のスクリーンショットは、インターフェイスをテストのために一緒にまとめる方法のアイディアを示します。
図 0.1 DOM テストページの例
この例では、背景色 (bgColor
) やハイパーリンクの色 (aLink
) や文字色 (text
) といった DOM からアクセス可能な Web ページの側面をドロップダウンメニューが動的に更新します。 しかし、あなたはあなたのテストページをデザインします。あなたが読んだことに関してインターフェイスをテストすることは、DOM の効果的な利用法を学ぶうえで大切なことです。