DOMとは
HTMLを読み込んだブラウザが、文書をメモリ内の木構造データへ変換して保持する仕組みのこと。
MDNでは以下のように説明されている。
ドキュメントオブジェクトモデル (Document Object Model, DOM) は、ウェブページを表す HTML のような文書の構造をメモリー内に表現することで、ウェブページとスクリプトやプログラミング言語を接続するものです。
ここで重要なのは、
- DOMはHTMLそのものではない
- ブラウザがHTMLを解析して作る「メモリ上の構造」
- JavaScriptから操作できるようにAPIとして提供されている
という点。
DOMとJavaScriptの関係
DOMはJavaScriptの機能そのものではない。
DOMはブラウザが提供しているWeb APIであり、
JavaScriptはそれを通してHTMLを操作している。
構造のイメージは以下の通り。
window
└─ document(DOMオブジェクト)
├─ getElementById()
├─ createElement()
├─ createTextNode()
JavaScriptという言語がHTMLを直接理解しているわけではない。
ブラウザが用意した document オブジェクトを経由して操作している。
要素(エレメント)、ノードとは
HTMLのタグで表された構造単位が要素。
DOMツリーという木構造を構成する最小単位がノード。
要素もノードの一種である。
ノードには種類がある。
- 要素ノード
- テキストノード
- 属性ノード
- コメントノード など
ノードは木構造を構成するすべての構成要素を含む概念。
<!DOCTYPE html>
<html lang="ja">
<head>
<title>日記</title>
</head>
<body>
<div id="lunch">
<h1>今日食べたもの</h1>
<p>二郎系ラーメン</p>
</div>
<div id="drama">
<h1>今日観たドラマ</h1>
<p>ストレンジャーシングス<strong>シーズン5</strong>
</p>
</div>
</body>
</html>
例えば、
-
<div>は要素ノード - 「二郎系ラーメン」はテキストノード
-
id="lunch"は属性ノード
のように、DOM上ではそれぞれ別のノードとして扱われる。
オブジェクトとは
オブジェクトとは、
データ(プロパティ)と振る舞い(メソッド)をひとまとめにした実体のこと。
状態を持ち、その状態を操作する機能を持つもの という理解。
例:
document.getElementById()
-
document→ オブジェクト -
getElementById→ メソッド -
valueなど → プロパティ
documentオブジェクトには、IDを検索するメソッドや、
入力されたテキストを取得するためのプロパティなどが用意されている。
参照とは
JavaScriptでDOMの中から特定の要素を取得する際、実際に渡されているのはメモリ上に存在するDOMオブジェクトへの参照(アドレス)である。
const e = document.getElementById('button');
このとき e に入っているのはボタンの複製ではなく、DOM上のボタン要素を指し示す参照 。
そのため、
e.textContent = "変更";
と書けば、実際の画面のボタン表示が変わる。
コピーではなく参照を扱っているから、 操作がそのままDOMに反映される。
コード解説
以下は「Add」ボタンを押すとテキストボックスに記入した文字がリストに追加され、「Delete」ボタンを押すと最後に追加した要素を削除するコード。
HTML
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<ul id="list">
</ul>
<input type="text" id="textBox">
<input type="button" id="button" value="Add">
<input type="button" id="deleteButton" value="Delete">
<script src="main2.js"></script>
</body>
</html>
JavaScript
'use strict';
// 厳格モードで実行
// 未宣言変数の使用を防ぐなど、バグの予防になる
const e = document.getElementById('button');
// documentオブジェクトのgetElementByIdメソッドで
// id="button" の要素を取得する
// ここで得られるのは要素ノードへの参照
e.addEventListener('click', () => {
// ボタンがクリックされたら以下の処理を実行
const textBox = document.getElementById('textBox');
// id="textBox" の入力要素を取得
const li = document.createElement('li');
// 新しいli要素ノードを生成
// この時点ではまだDOMツリーに追加されていない
// メモリ上に存在しているだけ
const text = document.createTextNode(textBox.value);
// textBox.value は入力された文字列
// それを使ってテキストノードを生成
li.appendChild(text);
// li要素の子ノードとしてテキストノードを追加
const listElement = document.getElementById('list');
// ul要素を取得
listElement.appendChild(li);
// ulの子要素としてliを追加
// ここで初めてDOMツリーが変更される
// DOMが変更されるとブラウザが再描画し、画面に反映される
}, false);
