DXコラム
DXコラム

目次

「DOM(ドム)」は、「Document Object Model(ドキュメント・オブジェクト・モデル)」の略称で、HTMLやXML文書をツリー状に構造化し、プログラムからその構造にアクセスや操作ができるようにする仕組みのことです。
たとえば、あるWebページに表示されている見出しや画像、リンクなども、すべてDOMを通してJavaScriptから操作できます。言い換えれば、DOMは「ブラウザ上のページを、プログラムで動かすための橋渡し役」ともいえる存在です。
そもそもWebページは、HTMLファイルとして書かれた「ただのテキスト」から始まります。しかし、ブラウザはそのテキストを読み込むと、画面上に表示するためにさまざまな処理を行います。そのとき生成されるのが「DOMツリー」です。
このDOMツリーがあるおかげで、JavaScriptはページ内の特定の要素を探し出し、見た目や内容を変更したり、新しい要素を追加したりできます。たとえば、ボタンを押したときに画像を切り替えるようなインタラクティブな動きも、すべてDOMの力によって実現されているのです。
DOMは「仕様(Standard)」として定義されている技術で、W3C(World Wide Web Consortium)やWHATWG(Web Hypertext Application Technology Working Group)といった業界団体が標準化を進めています。ただし、実際にこの仕様を「どうやって動かすか」は各ブラウザの実装に委ねられています。
そのため、同じJavaScriptのコードでも、ブラウザによってDOMの挙動が微妙に異なることがありました。近年は標準化が進み、そうした差異は減りつつありますが、DOMは「仕様」と「実装」が別物であることを知っておくと、理解がスムーズになります。

DOMは、HTMLやXMLの文書構造を「木(ツリー)」のような形で表現します。この構造の中で、各要素は「ノード(節)」と呼ばれます。
たとえば、HTMLの<html>タグが最上位の親ノードとなり、その中に<head>や<body>といった子ノードがぶら下がるイメージです。さらにその下には、タイトル、段落、画像、リンクといった要素が次々と子ノードとしてつながっていきます。
このように、DOMは要素同士の親子関係や兄弟関係を保ちながら、文書全体を階層構造として管理しています。
DOMを構成するノードには、いくつかの種類があります。よく使われるものをいくつか紹介しましょう。
・Documentノード:文書全体を表すノードで、DOMツリーの一番上に位置します。JavaScriptでいうとdocumentオブジェクトにあたります。
・Elementノード:HTMLの各タグ(例:<div>や<p>)がこれに該当します。ページの中の「部品」ともいえる存在です。
・Textノード:要素内のテキスト部分を扱うノードです。たとえば、段落の中にある文章などがこれにあたります。
他にもコメントノードや属性ノードといったものがありますが、Webページを操作する上では、主に上記の3つを意識していれば問題ありません。
Webページを表示する際、ブラウザはまずHTMLを読み込みます。このとき、読み込んだテキストデータを上から順に解析しながら、段階的にDOMツリーを構築していきます。
この処理は「パース」と呼ばれ、ページの表示と並行して進められるのが一般的です。そのため、HTMLの読み込みが完了する前でも、すでに一部のDOMが生成されていることがあります。
この「構築途中のDOM」へアクセスしようとすると、エラーが発生する場合もあるため、JavaScriptではDOMContentLoadedイベントなどを利用して「DOMが完全に構築されたタイミング」を見計らうことが大切です。

DOMを扱う上で、最も基本的かつ頻繁に使われるのが「要素の取得と変更」です。たとえば、ページ内の特定のボタンや見出しにアクセスして、その内容を差し替えたり、スタイルを変えたりできます。
JavaScriptでは、以下のようなメソッドを使って要素を取得します。
・document.querySelector(‘h1’):最初の <h1> 要素を取得
・document.getElementById(‘main’):IDが”main”の要素を取得
取得した要素は、textContent プロパティでテキストを変更できるほか、setAttributeメソッドで属性を操作することも可能です。たとえば、画像のsrcを動的に書き換えたり、リンク先を変更したりする場面でも使われます。
DOMの魅力は、ページを動かせる点にもあります。その中心となるのが「イベント処理」です。たとえば、ボタンがクリックされたタイミングで、ある処理を行いたい場合には、以下のように書きます。
document.querySelector(‘#myButton’).addEventListener(‘click’, function() {
alert(‘ボタンがクリックされました’);
});
このように、addEventListenerを使うことで、クリックや入力、スクロールなど、ユーザーの操作に対して柔軟に反応させることができます。
イベント処理をうまく使うことで、ページは単なる静的な文書から、動きのあるインタラクティブなUIへと変わっていきます。
DOM操作でよくあるつまずきとして、「動的に追加された要素にイベントが効かない」というケースがあります。
これは、ページ読み込み時点では存在していなかった要素には、事前にイベントが登録されていないためです。こうしたときは「イベント委譲*」と呼ばれる手法が有効です。親要素にイベントを登録し、子要素で発生したイベントを拾うようにすると、動的な要素にも柔軟に対応できます。
document.querySelector(‘#list’).addEventListener(‘click’, function(e) {
if (e.target.matches(‘.item’)) {
console.log(‘クリックされた要素:’, e.target);
}
});
*イベント委譲:親要素にイベントをまとめて設定して、子要素のイベントもまとめて処理する手法のこと
近年、ReactやVueなどのフレームワークを使う開発が主流となる中で、「仮想DOM(Virtual DOM)」という言葉を見かける機会が増えました。このように、DOMの操作やイベント処理には仕組みを知ることが何より大切です。見た目は簡単なコードでも、背後では細かいルールが働いていることを理解しておくと、トラブルに強くなれます。
仮想DOMとは、実際のDOMとは別にメモリ上に作られる仮のDOMです。これを使うことで、ページの更新内容を一度仮想DOMでシミュレーションし、差分だけを実DOMに反映させるという効率的な操作が可能になります。
実DOMの操作はどうしても処理が重くなりがちですが、仮想DOMを介すことで最小限の変更だけを実行できるため、パフォーマンスが向上します。言い換えれば、仮想DOMはDOM操作の「最適化を助ける中間役」のような存在です。
ただし、仮想DOM自体が「DOMの代替」ではなく、「DOMをより効率的に使うための仕組み」であることを誤解しないようにしたいところです。
DOMを直接操作すると、ブラウザはそのたびに画面のレイアウトを再計算したり、描画をやり直したりすることがあります。これを「リフロー」や「再描画(リペイント)」と呼びます。
頻繁なDOMの操作は、こうした再計算を何度も引き起こすため、ページの表示速度やユーザー体験に悪影響を与える原因となります。
たとえば、要素を1つずつ追加するよりも、まとめて「DocumentFragment*」に格納してから一括で挿入する方が、パフォーマンスに優れています。細かいことのようですが、意識するだけでスムーズな動きを実現しやすくなります。
*DocumentFragment:ノードの一種。複数のノードをまとめて扱うのに必要なものであり、ひとつの独立した木構造の頂点のノード

DOMは仕様として標準化されているとはいえ、すべてのブラウザが完全に同じように実装しているわけではありません。特に注意したいのが、Internet Explorerなどの旧ブラウザです。
たとえば、addEventListenerが使えないバージョンのIEでは、代わりにattachEventを使う必要があったり、classList*が未対応だったりと、思わぬバグの原因になることがあります。
最近の開発では、IEのサポートを終了しているケースが多くなってきましたが、特定の業界や業務システムでは依然として利用されている場合があります。ターゲットユーザーに応じた対応を考えることが大切です。
*classList:HTML要素に付いている class属性(クラス名)を簡単に操作するためのプロパティで、HTMLの見た目を動的に変えることができる
ここまでDOMとは何か、どのように使われるのかについて見てきました。DOMは一見すると難しそうに感じるかもしれませんが、Webページを動的に扱ううえで欠かせない基盤のような存在です。
JavaScriptを使って画面の内容を変えたり、ユーザーの操作に応じて動きを加えたりするには、DOMの理解が不可欠です。そしてその理解が深まれば、Web開発の自由度も一気に高まっていきます。
DOMの基本を押さえておくだけでも、Web開発の理解はぐっと進みます。「なんとなく難しそうだな」と感じていたとしても、ひとつひとつ試しながら触れていくことで、自然と慣れていくものです。
DOMの基礎をつかんだら、次は「イベント処理」や「非同期通信(fetchなど)」に進んでみるのがおすすめです。そこから、Reactなどのフレームワークに触れると、「仮想DOM」との違いもより実感しやすくなるはずです。
自分で「動くページ」を作ってみると、DOMの面白さをより深く体感できるかもしれませんね。
(文=広報室 白石)
あわせて読みたい記事: