要素ノード / テキストノードとは何か
要素ノードは HTML のタグそのもの(div, p, a など)を表し、属性(id, class, style など)や子ノードを持てます。テキストノードは、要素の中にある“文字列”そのものを表します。ここが重要です:画面に見える文字は、要素ノードの中に入っているテキストノードとして存在します。DOM は「要素」と「テキスト」が別ノードであることを理解すると、思い通りに選択・変更・挿入ができるようになります。
要素ノードの基礎(タグ・属性・子ノード)
取得と基本プロパティ
<h1 id="title" class="hero">こんにちは</h1>
HTMLconst el = document.querySelector("#title");
console.log(el.tagName); // "H1"
console.log(el.id); // "title"
console.log(el.className); // "hero"
JavaScript要素ノードはタグ名や属性を持ち、children(要素だけ)や childNodes(テキストやコメントも含む)で子を辿れます。
属性・クラス・スタイルの操作
el.setAttribute("data-role", "headline");
el.classList.add("highlight"); // CSS: .highlight { color: red; }
el.style.marginTop = "16px";
JavaScriptここが重要です:見た目の変更は style 直書きより classList を切り替えて CSS に任せると、再利用性と可読性が上がります。
テキストノードの基礎(文字列と空白)
テキストノードの正体を確認
const el = document.querySelector("#title");
const text = el.firstChild; // "こんにちは" を持つ Text ノード
console.log(text.nodeType); // 3(Text)
console.log(text.nodeValue); // "こんにちは"
JavaScriptテキストは独立したノードとして存在します。空白や改行もテキストノードになりうるため、要素だけを扱いたいときは children や nextElementSibling を使います。
安全に文字列を読み書きする
el.textContent = "ようこそ"; // テキストとして安全に代入(HTMLは解釈しない)
JavaScriptここが重要です:ユーザー入力や外部データを表示するなら textContent を使うと XSS を避けられます。HTML を展開したい特別な場合のみ innerHTML を使います。
children と childNodes の違い(選び分けの勘所)
要素だけを扱う場合
const list = document.querySelector("ul");
for (const li of list.children) {
console.log(li.tagName); // "LI"(要素のみ)
}
JavaScriptテキストやコメントも扱う場合
for (const node of list.childNodes) {
console.log(node.nodeType); // 1:要素, 3:テキスト, 8:コメント など
}
JavaScriptここが重要です:空白テキストが紛れるとロジックが狂います。UI操作は children、解析や整形では childNodes と使い分けるのが鉄則です。
作成・挿入・削除(要素とテキストの組み立て)
要素とテキストを生成して挿入
const p = document.createElement("p"); // 要素ノード
p.textContent = "説明文です"; // テキストノード(自動生成)
document.body.append(p); // ツリーに組み込み
JavaScriptテキストノードを直接作ることも可能
const t = document.createTextNode("追加の一文");
p.append(t);
JavaScript削除
p.remove(); // 親から取り外す
JavaScriptここが重要です:生成→内容設定→挿入の順にすると、中途半端な状態が画面に見えず、再描画も最小化できます。大量追加は DocumentFragment でまとめて挿入すると効率的です。
textContent / innerHTML / innerText の違い(深掘り)
用途に応じた選択
const box = document.querySelector("#box");
// 1) textContent: テキストとして安全に読み書き(最も推奨)
box.textContent = "<b>文字としてそのまま表示</b>";
// 2) innerHTML: HTML文字列を展開(タグが解釈される)
box.innerHTML = "<b>太字で表示</b>";
// 3) innerText: 実際に表示されるテキスト(CSSで非表示のものは除外・レイアウト計算が走る)
console.log(box.innerText);
JavaScriptここが重要です:
- セキュリティ重視なら
textContent。 - HTMLを挿入したいときのみ
innerHTML(信頼できるデータ限定)。 - 表示上のテキストを取得したいときは
innerText(ただし性能面で注意)。
兄弟・親子を正確に辿る(空白に惑わされない)
要素中心に辿る
const item = document.querySelector("li.active");
console.log(item.previousElementSibling); // 1つ前の要素
console.log(item.nextElementSibling); // 1つ後の要素
console.log(item.parentElement); // 親要素
JavaScriptテキストやコメントも含めて辿る
console.log(item.previousSibling); // テキストが返ることもある
console.log(item.nextSibling);
console.log(item.parentNode);
JavaScriptここが重要です:UIロジックは Element 系のプロパティを優先。ノード種別を混ぜると予期せぬ挙動になりがちです。
実践例:タイトルの差し替えと説明文の追加
<h1 id="title">こんにちは</h1>
<div id="panel"></div>
HTMLconst title = document.querySelector("#title");
const panel = document.querySelector("#panel");
// タイトルのテキストを安全に差し替え
title.textContent = "ようこそ";
// 説明文を作って挿入
const p = document.createElement("p");
p.textContent = "DOMでは要素とテキストが別ノードです。";
panel.append(p);
JavaScriptここが重要です:外部入力や変数から来た文字列は必ず textContent で扱い、HTMLが必要ならホワイトリストやテンプレートで厳格に制御しましょう。
よくある落とし穴(安全性・性能・タイミング)
- 未存在要素を操作して
null参照エラー。DOM構築後(deferやDOMContentLoaded)に触る。 innerHTMLの乱用で XSS やイベント喪失、再描画増加。基本は要素生成+textContent。- 読み取りと書き込みが交互に混ざるとパフォーマンス低下。変更はまとめて、スタイルはクラスで一括適用。
ここが重要です:要素ノードとテキストノードの役割を分けて捉え、正しい API を選ぶことで、安全・高速・予測可能な DOM 操作ができます。
まとめ
要素ノードは「タグと属性・子を持つ箱」、テキストノードは「その箱の中の文字」。UI操作では要素中心の API(children、classList、Element 系の sibling/parent)を、文字の読み書きでは textContent を基本に使い分けます。生成→設定→挿入の順で組み立て、空白テキストに惑わされない選択を習慣化すれば、DOM の挙動が直感的に理解でき、堅牢なインタラクションを作れるようになります。
