コンテンツにスキップ

JavaScript/Node

出典: フリー教科書『ウィキブックス(Wikibooks)』

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()