1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
|
---
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
---
<p><span class="seoSummary"><strong>Document Object Model</strong> (<strong>DOM</strong>) は、ウェブ上の文書のコンテンツと構造からなるオブジェクトのデータ表現です。このガイドでは、簡単に DOM を紹介します。</span> DOM がどのようにメモリ内で {{Glossary("HTML")}} または {{Glossary("XML")}} の文書を表現するか、どのように API を使用してウェブコンテンツやアプリケーションを作成するのかを見てみます。</p>
<h2 id="What_is_the_DOM" name="What_is_the_DOM">DOM とは</h2>
<p>Document Object Model (DOM) は HTML や XML 文書のためのプログラミングインターフェイスです。ページを表現するため、プログラムが文書構造、スタイル、内容を変更することができます。 DOM は文書をノードとオブジェクトで表現します。そうやって、プログラミング言語をページに接続することができます。</p>
<p>ウェブページは文書です。この文書はブラウザーのウィンドウに表示されるか HTML ソースとして表示することが可能です。しかし両方の場合においてもそれは同じ文書です。ドキュメントオブジェクトモデル (DOM) は、その同じ文書を表現、保存、操作する方法です。DOM はウェブページの完全なオブジェクト指向の表現で、 JavaScript のようなスクリプト言語から変更できます。</p>
<p><a class="external" href="http://www.w3.org/DOM/">W3C DOM</a> および <a class="external" href="https://dom.spec.whatwg.org">WHATWG DOM</a> 標準は、現代のブラウザーのほとんどで実装されています。多くのブラウザーは標準を拡張しているので、文書が様々なブラウザーの異なる DOM からアクセスされるウェブにおいては注意が必要です。</p>
<p>例えば、標準 DOM は以下のコードにおける <code>getElementsByTagName</code> メソッドが文書内のすべての <code><p></code> 要素のリストを返さなければならないと定義しています。</p>
<pre class="brush: js notranslate">const paragraphs = document.getElementsByTagName("p");
// paragraphs[0] は最初の <p> 要素
// paragraphs[1] は 2 番目の <p> 要素...
alert(paragraphs[0].nodeName);
</pre>
<p>ウェブページを操作したり、作成したりするために用意されているすべてのプロパティ、メソッド、イベントは、オブジェクトにまとめられています (例えば、文書自身を表現する <code>document</code> オブジェクトや、 HTML のテーブルにアクセスするための特別な {{domxref("HTMLTableElement")}} DOM インターフェイスを実装した <code>table</code> オブジェクト、などなど)。この文書では DOM について、オブジェクトごとのリファレンスを提供します。</p>
<p>現在の DOM は協調して動作する複数 API によって構築されています。コア <a href="/ja/docs/Web/API/Document_Object_Model">DOM</a> は、文書やその中のオブジェクトを基礎的に記述するオブジェクトを定義しています。これは必要に応じて DOM に新しい機能や能力を追加する他の API によって拡張されます。例えば、 <a href="/ja/docs/Web/API/HTML_DOM">HTML DOM API</a> はコア DOM に HTML 文書の表現の対応を追加しています。</p>
<h2 id="DOM_and_JavaScript" name="DOM_and_JavaScript">DOM と JavaScript</h2>
<p>このリファレンスでの例と同様に、上の短い例は {{glossary("JavaScript")}} で書かれています。つまり、 JavaScript で<em>書かれて</em>いますが、しかし DOM を<em>使用</em>してウェブページとその要素にアクセスしています。 DOM はプログラミング言語ではありませんが、これがないと、 JavaScript 言語はウェブページ、 HTML 文書、 XML 文書、およびその構成部品 (要素など) のモデルや記法を持っていません。文書内のすべての要素 — 全体としての文書、 head、文書内の表、表の見出し、表のセル内のテキスト — は、その文書のドキュメントオブジェクトモデルの一部ですので、 DOM と JavaScript のようなスクリプト言語を通してそれらすべてにアクセスし、操作することができます。</p>
<p>当初、 JavaScript と DOM は密接に絡み合っていましたが、最終的には別々の存在に進化しました。ページの内容は DOM に格納されており、 JavaScript を介してアクセスしたり操作したりすることができるので、この近似式を書くことができます。</p>
<p>API = DOM + JavaScript</p>
<p>DOM は特定のプログラミング言語に依存しないように設計されており、文書の構造表現を単一の一貫した API から利用できるようになっています。このリファレンス文書では JavaScript のみに焦点を当てていますが、この Python の例が示すように、DOM の実装はどのような言語にも対応できるようになっています。</p>
<pre class="brush: python notranslate"># 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")
</pre>
<p>ウェブで JavaScript を書くためにどのような技術が使われるのかについての詳細は、 <a href="/ja/docs/Web/JavaScript/JavaScript_technologies_overview">JavaScript 技術概要</a>をご覧ください。</p>
<h2 id="How_Do_I_Access_the_DOM.3F" name="How_Do_I_Access_the_DOM.3F">DOM へのアクセス</h2>
<p>DOM を使い始めるには、何も特別なものは必要ありません。異なるブラウザーは異なる DOM の実装をもっています。そして、これらの実装の実際の DOM の規格への適応度はさまざまです (この話題に関してはこの文書では避けます)。しかし、すべてのウェブラウザーはスクリプトからウェブページにアクセスできるように何らかのドキュメントオブジェクトモデルを持っています。</p>
<p>インラインの <code><script></code> 要素であろうとも、スクリプトを読み込む命令によってウェブページに埋め込まれていようとも、スクリプトを作れば、 {{domxref("document")}} や {{domxref("Window", "window")}} 要素といったウェブページ中のさまざまな要素に対するに API をすぐに使い始めることが出来ます。それらの API で文書自身を操作したり、文書の子要素を取り出したりできます。 DOM でのプログラミングは以下のように簡単に出来ます。1 つは、 {{domxref("Window", "window")}} オブジェクトの {{domxref("Window.alert", "alert()")}} 関数を利用し、警告メッセージを表示しています。より長い例はより洗練された DOM 関数を使い、実際に新しいコンテンツを作り出しています。</p>
<p>以下の JavaScript は、文書が読み込まれた時 (として DOM が利用可能になった時) にアラートを表示します。</p>
<pre class="brush: html notranslate"><body onload="window.alert('私のホームページへようこそ!');">
</pre>
<p>他の例です。この関数は新しい H1 要素を作成し、その要素にテキストを加え、文書のツリーに <code>H1</code> 要素を加えています。</p>
<pre class="brush: html notranslate"><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>
</pre>
<h2 id="Important_Data_Types" name="Important_Data_Types">基本的なデータ型</h2>
<p>このリファレンスでは、様々なオブジェクトと種類をなるべく簡単な方法で説明します。しかし、API に渡される、注意しなければならないデータ型はたくさんあります。</p>
<div class="blockIndicator note">
<p><strong>注:</strong> DOM を使用するコードの大部分は HTML 文書の操作を中心としているため、DOM 内のノードを<strong>要素</strong>と呼ぶのが一般的ですが、厳密にはすべてのノードが要素というわけではありません。</p>
</div>
<p>以下の表はこれらのデータの種類を簡単に説明しています。</p>
<table class="standard-table">
<thead>
<tr>
<th>データ型 (インターフェイス)</th>
<th>説明</th>
</tr>
</thead>
<tbody>
<tr>
<td>{{domxref("Document")}}</td>
<td>メンバーが <code>document</code> 型のオブジェクトを返すときは (例えば、element の <code>ownerDocument</code> 属性はそれが属する <code>document</code> を返します)、このオブジェクトはルートの <code>document</code> オブジェクト自身です。<a href="/ja/docs/Web/API/Document">DOM の <code>document</code> リファレンス</a>の章は <code>document</code> オブジェクトを説明しています。</td>
</tr>
<tr>
<td>{{domxref("Node")}}</td>
<td>文書内にあるすべてのオブジェクトは何らかの種類のノードです。 HTML 文書では、オブジェクトは要素ノードだけでなく、テキストノードや属性ノードもあります。</td>
</tr>
<tr>
<td>{{domxref("Element")}}</td>
<td><code>element</code> 型は <code>node</code> に基づいています。これは要素、または DOM API のメンバーから返される <code>element</code> 型のノードのことです。例えば、 {{domxref("document.createElement()")}} メソッドは <code>node</code> へのオブジェクト参照を返すというより、このメソッドは単に DOM によって生成された <code>element</code> を返すと言えます。 <code>element</code> オブジェクトは DOM の <code>Element</code> インターフェイスと、もっと基本的な <code>Node</code> インターフェイスも実装しており、両方がこの参照に含まれます。 HTML 文書では、要素はさらに HTML DOM API の {{domxref("HTMLElement")}} インターフェイスや、特定の種類の要素における能力を記述するためのその他のインターフェイス (例えば {{HTMLElement("table")}} 要素における {{domxref("HTMLTableElement")}}) によって更に拡張されています。</td>
</tr>
<tr>
<td>{{domxref("NodeList")}}</td>
<td><code>nodeList</code> は、 {{domxref("document.getElementsByTagName()")}} で返されるものなど要素の配列です。 <code>nodeList</code> 中の項目は、インデックスを使って以下の2つの方法で取得できます。
<ul>
<li>list.item(1)</li>
<li>list[1]</li>
</ul>
この二つの方法は等価です。最初の方法では、 <code>item()</code> は <code>nodeList</code> オブジェクトの一つの関数です。後者の方は、一般的な配列の構文を使い、リスト中の二つ目の項目を取得しています。</td>
</tr>
<tr>
<td>{{domxref("Attribute")}}</td>
<td><code>attribute</code> が (<code>createAttribute()</code> メソッドなどの) メンバーから返されたとき、属性のための特別な (ただし、小さな) インターフェイスを実装したオブジェクトの参照です。属性は要素のような DOM のノードですが、さほど使われません。</td>
</tr>
<tr>
<td>{{domxref("NamedNodeMap")}}</td>
<td><code>namedNodeMap</code> は配列のようですが、名前またはインデックスによって項目にアクセスきますが、後者は項目がリスト中に特定の順番で並んでいる訳ではないので、列挙するのに便利であるだけです。このために <code>namedNodeMap</code> には <code>item()</code> メソッドがあり、 <code>namedNodeMap</code> に項目を追加したり、削除したりすることができます。</td>
</tr>
</tbody>
</table>
<p>注意すべき用語の使い方がいくつかあります。例えば、ある {{domxref("Attribute")}} ノードを参照するのに単に <code>attribute</code> と呼んだり、 DOM ノードの配列を参照するのに <code>nodeList</code> と呼んだりします。このような用語は文書を通して紹介され使用されているのが分かるでしょう。</p>
<h2 id="DOM_interfaces" name="DOM_interfaces">DOM インタフェース</h2>
<p>このガイドは、 DOM 階層構造を操作するために利用できるオブジェクトと、実際の<em>もの</em>について触れます。どのように動作するかを理解する上で、混乱を催すかもしれない点がたくさんあります。例えば、 HTML の <code>form</code> 要素を表すオブジェクトには、 <code>name</code> プロパティが <code>HTMLFormElement</code> インターフェイスにある一方、 <code>className</code> プロパティが <code>HTMLElement</code> インターフェイスにあります。どちらにしても、求めるプロパティはその form オブジェクトの中にあります。</p>
<p>しかし、 DOM で実装されているオブジェクトとインターフェイスの関係は複雑なので、この節では、 DOM の仕様での実際のインターフェイスとそれがどのように利用できるかについて少し説明しようと思います。</p>
<h3 id="Interfaces_and_Objects" name="Interfaces_and_Objects">インターフェイスとオブジェクト</h3>
<p>多くのオブジェクトは複数のインターフェイスを受けついでいます。例えば、 table オブジェクトでは、特別な {{domxref("HTMLTableElement")}} インターフェイスを実装しており、そのインターフェイスは <code>createCaption</code> や <code>insertRow</code> などのメソッドを含んでいます。しかし、 <code>table</code> は HTML の要素でもあるので、 DOM の {{domxref("Element")}} リファレンスの章で説明している <code>Element</code> インターフェイスも実装しています。さらには、 HTML の要素は、 DOM を考慮する限り、ウェブページや XML ページのオブジェクトモデルを作りあげるノードのツリー内にあるノードもであるので、 table オブジェクトはより基本的な <code>Node</code> インターフェイスを、 <code>Element</code> から継承して実装しています。</p>
<p>次の例のように、 <code>table</code> オブジェクトの参照を入手したときは、おそらく無意識に、このオブジェクトの三つのインターフェイスをごく普通に交互に使います。</p>
<pre class="brush: js notranslate">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 = "注意: 太くなった枠線";
</pre>
<h3 id="Core_Interfaces_in_the_DOM" name="Core_Interfaces_in_the_DOM">DOM の中で核となるインターフェイス</h3>
<p>この節では、 DOM の中で最もよく使われるインターフェイスを列挙します。API がここで何をしているか記述するのではなく、DOM の中で非常に良く使われる関数や属性をちょっと示すのが狙いです。これらよく使われる API はこの本の最後の <a href="/ja/docs/Web/API/Document_Object_Model/Examples">DOM の例</a>の章のより長い例の中で使われています。</p>
<p><code>document</code> と <code>window</code> オブジェクトが一般的に DOM プログラミングの中で最もよく使われます。簡単に言うと、 <code>window</code> オブジェクトはブラウザーのようなものを表現し、 <code>document</code> オブジェクトは文書のルート自身です。 <code>Element</code> は一般的な <code>Node</code> インターフェイスを継承していて、あわせてこの 2 つのインターフェイスはここの要素で使われる多くの関数と属性を提供します。前節での <code>table</code> オブジェクトの例のように、これの要素はそれぞれが持つデータを扱うための特定のインターフェイスを持っている場合があります。</p>
<p>以下は、 DOM を使うウェブや XML ページのスクリプトでよく使われる API の簡単な一覧です。</p>
<ul>
<li><code>{{domxref("document.getElementById", "", "", "1")}}(id)</code></li>
<li><code>document.{{domxref("Element.getElementsByTagName", "getElementsByTagName", "", "1")}}(name)</code></li>
<li><code>{{domxref("document.createElement", "", "", "1")}}(name)</code></li>
<li><code>parentNode.{{domxref("Node.appendChild", "appendChild", "", "1")}}(node)</code></li>
<li><code>element.{{domxref("element.innerHTML", "innerHTML", "", "1")}}</code></li>
<li><code>element.{{domxref("HTMLElement.style", "style", "", "1")}}.left</code></li>
<li><code>element.{{domxref("element.setAttribute", "setAttribute", "", "1")}}()</code></li>
<li><code>element.{{domxref("element.getAttribute", "getAttribute", "", "1")}}()</code></li>
<li><code>element.{{domxref("EventTarget.addEventListener", "addEventListener", "", "1")}}()</code></li>
<li><code>{{domxref("window.content", "", "", "1")}}</code></li>
<li><code>{{domxref("window.onload", "", "", "1")}}</code></li>
<li><code>{{domxref("window.scrollTo", "", "", "1")}}()</code></li>
</ul>
<h2 id="Testing_the_DOM_API" name="Testing_the_DOM_API">DOM API のテスト</h2>
<p>この文書は、ウェブ開発に利用できるあらゆるインターフェイスの例を提供しています。いくつかの場合では、サンプルは完全な HTML ページで、これは DOM アクセスは <script> 要素の中に入っており、フォームのスクリプトを起動するのに必要なインターフェイス (例えば、ボタン) があり、DOM が操作する HTML 要素がリストされています。この場合は、例を新しい HTML 文書にカット・アンド・ペーストし、保存し、ブラウザーから例を走らせることができます。</p>
<p>しかし、いくつかのケースでは例はより簡潔です。HTML 要素のインターフェイスの基本的な関係を示すだけの例を走らせるために、インターフェイスがスクリプトから簡単にアクセスできるようなテストページを準備したいと思うかもしれません。以下の非常に簡単なウェブページはインターフェイスをテストする関数をおけるようにするヘッダー中の <script> 要素と、習得・設定・操作できる属性を持ったいくつかの HTML 要素と、ブラウザーからこれらの関数を呼ぶのに必要なウェブのユーザーインターフェイスを提供しています。</p>
<p>あなたが興味のある DOM インターフェイスをテストするために、このテストページや似たようなものを作ることができますし、ブラウザー上でどのように動くか見れます。必要であれば <code>test()</code> 関数の中身を更新したり、もっとボタンを作ったり、必要な要素を追加したりできます。</p>
<pre class="brush: html notranslate"><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>
</pre>
<p>例えば、ウェブページの色に影響する一連の属性のように、たくさんのインターフェイスを一つのページでテストするために、ボタンやテキスト入力欄、その他の HTML 要素を全部集めた似たようなテストページを作ることができます。以下のスクリーンショットは、インターフェイスをテストのために一緒にまとめる方法のアイディアを示します。</p>
<figure>
<figcaption>図 0.1 DOM テストページの例</figcaption>
<img alt="画像:DOM_Ref_Introduction_to_the_DOM.gif" class="internal" src="/@api/deki/files/173/=DOM_Ref_Introduction_to_the_DOM.gif"></figure>
<p>この例では、ウェブページの DOM からアクセス可能であるという側面から、ドロップダウンメニューの背景色 (<code>bgColor</code>) やハイパーリンクの色 (<code>aLink</code>) や文字色 (<code>text</code>) を動的に更新します。しかし、読んだことについてインターフェイスをテストするテストページを設計してみることは、 DOM の使い方を効果的に学ぶ上で重要なことです。</p>
<h2 id="Subnav">Subnav</h2>
<ul>
<li><a href="/ja/docs/Web/API/Document_Object_Model">DOM リファレンス</a></li>
<li><a href="/ja/docs/Web/API/Document_Object_Model/Introduction">DOM の紹介</a></li>
<li><a href="/ja/docs/Web/API/Document_Object_Model/Events">イベントと DOM</a></li>
<li><a href="/ja/docs/Web/API/Document_Object_Model/Examples">例</a></li>
</ul>
<div>{{DefaultAPISidebar("DOM")}}</div>
|