JavaScript/Node

Nodeオブジェクト

JavaScriptでDOM(Document Object Model)を操作する際、中心となるのが「Node」オブジェクトです。Nodeオブジェクトはウェブページを構成する要素の基盤となるインターフェースであり、すべてのDOM要素の親となります。

Nodeオブジェクトの基本概念

Nodeオブジェクトは、ドキュメント内のあらゆる要素(要素ノード、テキストノード、コメントノードなど)の基底となるオブジェクトです。HTMLドキュメントの構造はNodeオブジェクトの木構造(ツリー)として表現されます。

// ドキュメント自体もNodeオブジェクト
console.log(document.nodeType); // 9 (DOCUMENT_NODE)

// body要素もNodeオブジェクト
console.log(document.body.nodeType); // 1 (ELEMENT_NODE)

// テキストもNodeオブジェクト
const textNode = document.createTextNode("これはテキストノードです");
console.log(textNode.nodeType); // 3 (TEXT_NODE)

Nodeの種類

Nodeには12種類の型が存在しますが、実際によく使用されるのは以下の主要な型です:

nodeType 定数名 説明
1 ELEMENT_NODE HTML要素(divやpなど)
3 TEXT_NODE テキスト内容
8 COMMENT_NODE HTMLコメント
9 DOCUMENT_NODE ドキュメントオブジェクト
10 DOCUMENTTYPENODE DOCTYPE宣言
11 DOCUMENTFRAGMENTNODE DocumentFragment
// nodeTypeを使用して要素の種類を確認する例
function checkNodeType(node) {
    switch (node.nodeType) {
        case Node.ELEMENT_NODE:
            return "要素ノード: " + node.tagName;
        case Node.TEXT_NODE:
            return "テキストノード: " + node.nodeValue;
        case Node.COMMENT_NODE:
            return "コメントノード: " + node.nodeValue;
        default:
            return "その他のノード: " + node.nodeType;
    }
}

// 使用例
const element = document.querySelector("div");
console.log(checkNodeType(element)); // "要素ノード: DIV"

Nodeオブジェクトの主要プロパティ

Nodeオブジェクトには多くの便利なプロパティがあります:

プロパティ 説明
nodeType ノードの種類を表す数値
nodeName ノードの名前(要素の場合はタグ名、大文字)
nodeValue ノードの値(テキストノードやコメントノードの内容)
textContent ノードとその子孫のテキスト内容
parentNode 親ノード
childNodes 子ノードのNodeListオブジェクト
firstChild 最初の子ノード
lastChild 最後の子ノード
nextSibling 次の兄弟ノード
previousSibling 前の兄弟ノード
// divを作成
const div = document.createElement("div");
div.innerHTML = "親ノード<span>子ノード</span>末尾テキスト";

// 各プロパティの確認
console.log(div.nodeName); // "DIV"
console.log(div.nodeValue); // null(要素ノードの場合はnull)
console.log(div.textContent); // "親ノード子ノード末尾テキスト"
console.log(div.childNodes.length); // 3(テキスト、span、テキスト)
console.log(div.firstChild.nodeValue); // "親ノード"
console.log(div.childNodes[1].nodeName); // "SPAN"

Nodeオブジェクトの主要メソッド

Nodeオブジェクトには、DOM操作のための多くのメソッドが用意されています:

メソッド 説明
appendChild(node) 子ノードを末尾に追加
insertBefore(newNode, referenceNode) 指定したノードの前に新しいノードを挿入
removeChild(node) 子ノードを削除
replaceChild(newNode, oldNode) 子ノードを置換
cloneNode(deep) ノードのコピーを作成(deepがtrueなら子ノードも複製)
contains(node) 指定したノードが子孫に含まれているか確認
hasChildNodes() 子ノードが存在するかどうかを確認
isEqualNode(node) 指定したノードと同一かどうかを確認
// 要素の作成と操作
const parent = document.createElement("div");
const child1 = document.createElement("p");
const child2 = document.createElement("span");
const child3 = document.createElement("strong");

child1.textContent = "これは段落です";
child2.textContent = "これはspanです";
child3.textContent = "これは強調テキストです";

// 要素の追加
parent.appendChild(child1);
parent.appendChild(child2);

// 要素の挿入
parent.insertBefore(child3, child1);

// 要素の確認
console.log(parent.innerHTML);
// <strong>これは強調テキストです</strong><p>これは段落です</p><span>これはspanです</span>

// 要素の削除
parent.removeChild(child2);
console.log(parent.innerHTML);
// <strong>これは強調テキストです</strong><p>これは段落です</p>

// 要素の複製
const clone = child1.cloneNode(true);
clone.textContent = "これは複製された段落です";
parent.appendChild(clone);
console.log(parent.innerHTML);
// <strong>これは強調テキストです</strong><p>これは段落です</p><p>これは複製された段落です</p>

テキストノードの操作

テキストノードはHTML文書内のテキスト部分を表し、多くの場合、要素ノードの子ノードとして存在します。

// テキストノードの作成と操作
const paragraph = document.createElement("p");
const textNode = document.createTextNode("初期テキスト");
paragraph.appendChild(textNode);

// テキストノードの内容を変更
textNode.nodeValue = "変更後のテキスト";
console.log(paragraph.innerHTML); // "変更後のテキスト"

// textContentを使用した簡便な方法
paragraph.textContent = "さらに変更されたテキスト";
console.log(paragraph.innerHTML); // "さらに変更されたテキスト"

DocumentFragmentの活用

DocumentFragmentはドキュメントに直接表示されない軽量なノードコンテナで、複数のノードをまとめて追加する際に便利です。

// DocumentFragmentの使用例
const fragment = document.createDocumentFragment();
const container = document.createElement("div");

// fragmentに複数の要素を追加
for (let i = 0; i < 3; i++) {
    const paragraph = document.createElement("p");
    paragraph.textContent = `段落 ${i+1}`;
    fragment.appendChild(paragraph);
}

// 一度にすべての要素をDOMに追加(再描画は1回のみ)
container.appendChild(fragment);
document.body.appendChild(container);

console.log(container.innerHTML);
// <p>段落 1</p><p>段落 2</p><p>段落 3</p>

Node操作と互換性

古いブラウザではNode関連のAPIにいくつかの互換性の問題がありますが、現代のブラウザではほとんどのNode関連メソッドが適切にサポートされています。

// クロスブラウザ対応のための関数例
function insertAfter(newNode, referenceNode) {
    if (referenceNode.nextSibling) {
        referenceNode.parentNode.insertBefore(newNode, referenceNode.nextSibling);
    } else {
        referenceNode.parentNode.appendChild(newNode);
    }
}

// 使用例
const parent = document.createElement("div");
const firstChild = document.createElement("p");
const secondChild = document.createElement("span");

parent.appendChild(firstChild);
insertAfter(secondChild, firstChild);
console.log(parent.innerHTML); // <p></p><span></span>

まとめ

Nodeオブジェクトは、DOM操作の基盤となる重要な概念です。要素の作成、追加、削除からテキスト操作まで、JavaScriptを使ってウェブページを動的に操作するために必要な機能を提供します。Nodeオブジェクトの性質と操作方法を理解することで、より効率的で柔軟なDOM操作が可能になります。

附録

静的プロパティ

Node.ATTRIBUTE_NODE
Node.CDATA_SECTION_NODE
Node.COMMENT_NODE
Node.DOCUMENT_FRAGMENT_NODE
Node.DOCUMENT_NODE
Node.DOCUMENT_POSITION_CONTAINED_BY
Node.DOCUMENT_POSITION_CONTAINS
Node.DOCUMENT_POSITION_DISCONNECTED
Node.DOCUMENT_POSITION_FOLLOWING
Node.DOCUMENT_POSITION_IMPLEMENTATION_SPECIFIC
Node.DOCUMENT_POSITION_PRECEDING
Node.DOCUMENT_TYPE_NODE
Node.ELEMENT_NODE
Node.ENTITY_NODE
Node.ENTITY_REFERENCE_NODE
Node.NOTATION_NODE
Node.PROCESSING_INSTRUCTION_NODE
Node.TEXT_NODE
Node.arguments
Node.caller
Node.length
Node.name
Node.prototype

静的アクセサ

静的メソッド

継承関係

ObjectEventTargetNode

Nodeのインスタンスプロパティ

Node.prototype.ATTRIBUTE_NODE
Node.prototype.CDATA_SECTION_NODE
Node.prototype.COMMENT_NODE
Node.prototype.DOCUMENT_FRAGMENT_NODE
Node.prototype.DOCUMENT_NODE
Node.prototype.DOCUMENT_POSITION_CONTAINED_BY
Node.prototype.DOCUMENT_POSITION_CONTAINS
Node.prototype.DOCUMENT_POSITION_DISCONNECTED
Node.prototype.DOCUMENT_POSITION_FOLLOWING
Node.prototype.DOCUMENT_POSITION_IMPLEMENTATION_SPECIFIC
Node.prototype.DOCUMENT_POSITION_PRECEDING
Node.prototype.DOCUMENT_TYPE_NODE
Node.prototype.ELEMENT_NODE
Node.prototype.ENTITY_NODE
Node.prototype.ENTITY_REFERENCE_NODE
Node.prototype.NOTATION_NODE
Node.prototype.PROCESSING_INSTRUCTION_NODE
Node.prototype.TEXT_NODE
Node.prototype [ Symbol.toStringTag ]

Nodeのインスタンスアクセサ

get Node.prototype.baseURI
get Node.prototype.childNodes
get Node.prototype.firstChild
get Node.prototype.isConnected
get Node.prototype.lastChild
get Node.prototype.nextSibling
get Node.prototype.nodeName
get Node.prototype.nodeType
get Node.prototype.nodeValue
get Node.prototype.ownerDocument
get Node.prototype.parentElement
get Node.prototype.parentNode
get Node.prototype.previousSibling
get Node.prototype.textContent

Nodeのインスタンスメソッド

Node.prototype.appendChild()
Node.prototype.cloneNode()
Node.prototype.compareDocumentPosition()
Node.prototype.constructor()
Node.prototype.contains()
Node.prototype.getRootNode()
Node.prototype.hasChildNodes()
Node.prototype.insertBefore()
Node.prototype.isDefaultNamespace()
Node.prototype.isEqualNode()
Node.prototype.isSameNode()
Node.prototype.lookupNamespaceURI()
Node.prototype.lookupPrefix()
Node.prototype.normalize()
Node.prototype.removeChild()
Node.prototype.replaceChild()

EventTargetのインスタンスプロパティ

EventTarget.prototype [ Symbol.toStringTag ]

EventTargetのインスタンスアクセサ

EventTargetのインスタンスメソッド

EventTarget.prototype.addEventListener()
EventTarget.prototype.constructor()
EventTarget.prototype.dispatchEvent()
EventTarget.prototype.removeEventListener()
カテゴリ:JavaScript
カテゴリ:JavaScript