DOM(Document Object Model)ツリーの構造は、HTMLやXMLドキュメントの内容をプログラムで操作・変更するための中核的な概念です。ウェブ開発やフロントエンドエンジニアリングに携わるすべての開発者にとって、DOMツリーの理解とそのノード(節)間の効率的なナビゲーション(移動)は不可欠です。本記事では、DOMツリーの概念から始め、ノードの種類、プロパティ、ナビゲーション手法、実践例、注意点に至るまで、完全かつ包括的に詳述していきます。
DOMツリーとは何か?
DOMツリーとは、ウェブページのHTML構造を木構造(ツリー構造)として表したものです。各HTML要素が「ノード(node)」と呼ばれる単位で表現され、親子関係・兄弟関係など、論理的な構造を持っています。

たとえば、以下のようなシンプルなHTMLは、
htmlhtml>
<html>
<head>
<title>サンプルtitle>
head>
<body>
<h1>見出しh1>
<p>段落p>
body>
html>
次のようなDOMツリーに変換されます。
bashDocument
└── html
├── head
│ └── title
│ └── テキストノード("サンプル")
└── body
├── h1
│ └── テキストノード("見出し")
└── p
└── テキストノード("段落")
DOMノードの種類
DOMツリー内の「ノード」はすべて同じではありません。以下に主要なノードの種類を整理します。
ノードの種類 | 説明 |
---|---|
Document ノード |
ページ全体のルート |
Element ノード |
HTMLの各タグ(例:
、
|
Text ノード |
タグ内のテキスト |
Comment ノード |
HTMLコメント( ) |
Attribute ノード |
要素の属性(class 、id など) |
これらのノードは、JavaScriptにより動的にアクセス・変更可能です。
DOMナビゲーション:ノード間の移動
DOMをナビゲートするとは、あるノードから別のノードへプログラム的に「移動」することを意味します。代表的なプロパティやメソッドは以下の通りです。
子ノードへの移動
-
firstChild
: 最初の子ノードを取得 -
lastChild
: 最後の子ノードを取得 -
childNodes
: 子ノードのリスト(NodeList)
javascriptconst parent = document.body;
console.log(parent.firstChild); // 最初の子ノード
親ノードへの移動
-
parentNode
: 親ノードを取得
javascriptconst heading = document.querySelector("h1");
console.log(heading.parentNode); //
兄弟ノードへの移動
-
nextSibling
: 次の兄弟ノード -
previousSibling
: 前の兄弟ノード
javascriptconst heading = document.querySelector("h1");
console.log(heading.nextSibling); //
か 空白のTextノード
要素ノード専用のナビゲーション
-
children
: 要素ノードのみの子ノード(HTMLCollection) -
firstElementChild
/lastElementChild
-
nextElementSibling
/previousElementSibling
javascriptconst section = document.body;
console.log(section.children); // h1, p のみ(Textノード除外)
ノードの探索(トラバーサル)
ナビゲーションと似ていますが、「探索(traversal)」では特定の条件に合致するノードを再帰的または選択的に見つける処理が行われます。
再帰的な探索例
javascriptfunction printAllNodes(node) {
console.log(node.nodeName);
for (let child of node.childNodes) {
printAllNodes(child);
}
}
printAllNodes(document.documentElement);
クエリセレクタを使った選択的探索
-
querySelector
/querySelectorAll
:CSSセレクタに基づいたノード取得
javascriptconst title = document.querySelector("title");
const allParagraphs = document.querySelectorAll("p");
ノード情報の取得と操作
ノードの型
各ノードには型が定義されています。
ノード型 | 数値定義 | 内容 |
---|---|---|
ELEMENT_NODE |
1 | HTMLタグなど |
TEXT_NODE |
3 | テキスト |
COMMENT_NODE |
8 | コメント |
javascriptnode.nodeType === Node.ELEMENT_NODE // true or false
ノード名と内容
-
nodeName
: ノードの名前(タグ名など) -
nodeValue
: ノードの値(テキストなど)
javascriptconst textNode = document.createTextNode("こんにちは");
console.log(textNode.nodeValue); // "こんにちは"
実践:DOMナビゲーションを活用した動的変更
以下は、DOMツリーをナビゲートしながら要素を動的に変更する例です。
javascript// 最初の段落の内容を変更
const firstParagraph = document.querySelector("p");
firstParagraph.textContent = "新しい内容です";
// 次の兄弟要素のスタイルを変更
const heading = document.querySelector("h1");
const nextElement = heading.nextElementSibling;
nextElement.style.color = "red";
DOMナビゲーションでよくある落とし穴
テキストノードと空白
childNodes
やfirstChild
などを使うと、空白や改行もテキストノードとして認識される点に注意。
html<body>
<h1>タイトルh1>
<p>本文p>
body>
上記構造でも、body.childNodes.length
は意外にも 5
になる可能性があります(テキストノード含むため)。
回避策:
-
children
やfirstElementChild
を使うことで、要素ノードのみに限定可能。
nullチェックの重要性
以下のように nextElementSibling
が null
の場合もあるため、必ずチェックを行うこと。
javascriptif (element.nextElementSibling !== null) {
element.nextElementSibling.textContent = "次の要素";
}
表:DOMナビゲーションの主なプロパティとその説明
プロパティ名 | 対象ノード | 説明 |
---|---|---|
parentNode |
すべて | 親ノード |
childNodes |
要素ノード | 子ノード全体(Text含む) |
children |
要素ノード | 要素のみの子ノード |
firstChild |
要素ノード | 最初の子ノード(Text含む) |
firstElementChild |
要素ノード | 最初の子要素 |
lastChild |
要素ノード | 最後の子ノード |
nextSibling |
任意ノード | 次の兄弟ノード(Text含む) |
nextElementSibling |
要素ノード | 次の要素ノード |
previousSibling |
任意ノード | 前の兄弟ノード |
previousElementSibling |
要素ノード | 前の要素ノード |
結論と今後の活用
DOMナビゲーションは、クライアントサイドJavaScriptにおけるページ操作の根幹です。静的なHTMLページを、動的で対話的なユーザー体験へと進化させるためには、DOMノードの構造理解とそれに基づいた適切な操作が不可欠です。特に、空白やテキストノードに起因するバグ、選択的探索の効率化、セレクタの使い分けなど、現場での実践力が求められます。
開発者はこれらのナビゲーション手法を熟知し、アクセシビリティ・パフォーマンス・保守性を念頭に置いたDOM操作を行うことで、より洗練されたウェブアプリケーションを構築することができるでしょう。
参考文献
-
MDN Web Docs: DOM Navigation
-
WHATWG DOM仕様書(https://dom.spec.whatwg.org/)
-
W3C DOM Level 2 Core Specification
読者である日本の皆様にとって、本記事がDOMツリーの理解と実践において貴重な手引きとなることを願ってやみません。