JavaScriptを使ってWebページに動きを付けるには、DOMの操作が必要です。
しかし、DOMは直感的に理解しにくく、説明を読んでもイマイチ分からないことが良くあります。

DOM操作には多くの方法がありますが、その前にDOMの仕組みや構造を知ることが大切です。
そこで今回は、初学者の方でも分かるように、DOMとは何かやさしく解説していきます。

DOM

DOMとは、「Document Object Model」の略で、Webページ全体のコンテンツをオブジェクトとして表現します。
DOMは、JavaScriptなどのプログラミング言語から、オブジェクトを扱うためのAPIを提供しています。

通常、何もしていないHTMLファイルの中身は、JavaScript側で操作することはできません。
しかし、HTMLファイルの中身をそれぞれオブジェクトとして捉え、JavaScriptから特定のオブジェクトにアクセスすることで、Webページの見た目を変更することができます。

つまりDOMとは、JavaScriptからHTMLの「どこ」に「何」をするのか実現するための仕組みということです。

例えば、document.bodyは、bodyタグを表すオブジェクトということになります。
以下は、HTML側の背景色を青に変えるコードです。

// HTMLドキュメントのbodyの背景を青に変える
document.body.style.background = 'blue';

数ある中の一例であるため、ここで覚える必要はありません。
DOM操作については別記事で解説するため、イメージができていれば大丈夫です。

DOMの構造

DOMの役割がなんとなくイメージできたところで、もう少しDOMの中身を見ていきましょう。

DOMには、次の特徴があります。

  • DOMツリーと呼ばれる階層構造
  • HTMLの各要素をノードで表す

DOMツリー

DOMは、枝分かれした木の性質のような階層構造を持っています。その構造のことをDOMツリーと呼びます。

次のHTMLドキュメントがあるとします。

<!DOCTYPE html>
<html>
<head>
  <title>タイトル</title>
</head>
<body>
  <h1>見出し</h1>
  <p>段落</p>
</body>
</html>

DOMは、このようにHTMLタグをDOMツリーとして表現します。

document 
  └── html 
       ├── head 
       │    └── title 
       │          └── #text タイトル
       └── body 
            ├── h1 
            │    └── #text 見出し
            └─── p
                 └── #text 段落

<html><body><h1>などすべてのHTMLタグはオブジェクトです。

documentを最上階として、その下にはhtml、さらにその下にはheadとbodyと続くようにツリー構造が作られていきます。
普段、書いているHTMLのコードは、無意識のうちにこのようなツリー構造に沿って作られていたということです。

ノード

HTMLに書かれている各要素は、DOMツリーの中ではノードと呼ばれます。

ノードには、次の種類があります。

ノードの種類 説明
ドキュメントノード 全体を表すdocumentオブジェクト
要素ノード 要素を表すオブジェクト
テキストノード 要素内のテキストを表すオブジェクト
属性ノード 要素の属性を表すオブジェクト
コメントノード コメントを表すオブジェクト

次のHTMLドキュメントを見てください。

<!DOCTYPE html>
<html>
<head>
  <title>タイトル</title>
</head>
<body>
  <h1>見出し</h1>
  <!-- ここから本文 -->
  <p id="text">段落</p>
</body>
</html>

上記のコードをDOMツリーで表すとこのようになります。

document 
  └── html
       ├── head
       │    └── title
       │         └── #text タイトル
       └── body
            ├── h1
            │    └── #text 見出し
            ├── #comment ここから本文
            │
            └─── p ─── id
                 └── #text 段落

最上階にあるdocumentがドキュメントノードです。
headやbody、h1やpなど、HTMLドキュメントの要素を表すのが要素ノードとなります。

さらに、要素内のテキストにはテキストノードが生成され、#textというラベルが貼られます。
要素に付随するidは、属性ノードです。
コメントがある場合、#commentとラベル付けされたコメントノードが作られます。

このように、HTML上のすべての要素をノードとして表現します。

ノードの関係性

DOMツリーの位置に応じて各ノードの関係が存在します。

ノードには、次の種類があります。

  • ルートノード
  • 親ノード
  • 子ノード
  • 子孫ノード
  • 兄弟ノード

次のDOMツリーを見てください。

document 
  └── html 
       ├── head 
       │    └── title 
       │         
       └── body 
            ├── h1 
            │    
            └── p                               

すべてのノードを包括している最上位のノードのことをルートノードと呼びます。ここではdocumentがルートノードとなります。
htmlは、documentの子ノードであり、headとbodyの親ノードです。
また、h1とpは互いに兄弟ノードであり、htmlの子孫ノードとなります。

空白ノード

HTMLドキュメントの中のスペースや改行は、DOMの中では空白ノードと呼びます。
空白ノードは、テキストノードとして扱われます。

次の2つのHTMLドキュメントは、ブラウザではまったく同じように表示されます。

<div><h2>見出し</h2><p>段落</p></div>
<div>
  <h2>見出し</h2>
  <p>段落</p>
</div>

通常、HTMLドキュメントをブラウザで表示した場合、要素の前後にある空白や改行は表示されません。
一定のルールに沿って空白が無視されるためです。

しかし、DOMツリーでは異なる構造を持っています。

div 
  ├── h2 
  │   └── #text 見出し
  └── p
      └── #text 段落                            
div 
  ├── 空白
  ├── h2 
  │   └── #text 見出し
  ├── 空白
  ├── p
  │   └── #text 段落   
  └── 空白                            

要素の前後に空白や改行がある場合、空白ノードとして認識されます。

今後DOMの操作を行う際に、ノードを取得する機会があります。
その際に、空白があるかないかで処理が異なることがあるため、空白ノードについても頭に入れておくと良いでしょう。

まとめ

今回は、DOMの仕組みや構造について解説しました。

// ポイント
* DOMは、Webページ全体のコンテンツをオブジェクトとして捉える
* HTMLドキュメントを枝分かれ構造のDOMツリーとして表現する
* HTML上のすべての要素をノードとして表現する
* テキストや空白、コメントもノードとして扱われる

DOMの構造が分かると今後のDOM操作の理解に役立ちます。ぜひ参考にしてください。

合わせて読みたいDOMシリーズ

第1回:DOMの仕組みと構造(当記事)
第2回:DOMナビゲーション
第3回:要素ノードの検索 -getElement
第4回:要素ノードの検索 -guerySelector
第5回:ノードの種類・名前・値の取得
第6回:HTMLコンテンツの取得と書き込み -innerHTML
第7回:テキストの取得と書き込み -textContent
第8回:要素の属性の取得・設定・削除
第9回:要素のスタイルの取得・設定・削除
第10回:新しいノードの作成
第11回:ノードの追加・置き換え・削除
第12回:要素にテキストを追加する方法
第13回:クラスの変更 -classList