DocumentFragment

javascript

DocumentFragment

DocumentFragmentは通常のノードとは少し違い、複数のノードをまとめて持つことができます。

また、単独で存在し、使用することができます。

DocumentFragmentのノードは、parentNodeを持つことがなくnullになります。
子ノードを持つことができるので、そのノードは操作することができます。

DocumentFragmentを使った実例を使って、どんな動きをするのかを確認してみます。

まずは、DocumentFragmentを作成してみます。

<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="UTF-8">
<title>テストHTML</title>
</head>
<body>

<div id="p1" name="p1name">
	<div id="c1" name="c1name">c1text</div>
	<div id="c2" name="c2name">c2text</div>
	<div id="c3" name="c3name">c3text</div>
</div>

<script type="text/javascript">
// DocumentFragmentを作成する
let frag = document.createDocumentFragment();

console.log(frag);

</script>

</body>
</html>

サーバ上のHTMLはこちら(test1.html)

出力結果ですが、コンソールログには以下のように出力されます。

DocumentFragment []
​
baseURI: "https://propansystem.net/blogsample/js/040/test1.html"
​
childElementCount: 0
​
childNodes: NodeList []
​
children: HTMLCollection { length: 0 }
​
firstChild: null
​
firstElementChild: null
​
isConnected: false
​
lastChild: null
​
lastElementChild: null
​
nextSibling: null
​
nodeName: "#document-fragment"
​
nodeType: 11
​
nodeValue: null
​
ownerDocument: HTMLDocument https://propansystem.net/blogsample/js/040/test1.html
​
parentElement: null
​
parentNode: null
​
previousSibling: null
​
textContent: ""
​
<prototype>: DocumentFragmentPrototype { getElementById: getElementById(), querySelector: querySelector(), querySelectorAll: querySelectorAll(), … }

これは内容が空のDocumentFragmentノードが生成されたことを表します。

また、DocumentFragmentノードを作成しただけでは、まだHTMLドキュメントには何も影響を及ぼさないです。

別な方法だと、オブジェクトのコンストラクタを使用してnewすることもできます。

let frag = new DocumentFragment();

上記のように書くと同じノード「frag」が生成されます。

DocumentFragmentを使ってノードを生成する

では次にDocumentFragmentを使ってHTMLドキュメントに対してノードを追加してみます。

先ほどのHTMLサンプルに次のコードを追記しました。

<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="UTF-8">
<title>テストHTML</title>
</head>
<body>

<div id="p1" name="p1name">
	<div id="c1" name="c1name">c1text</div>
	<div id="c2" name="c2name">c2text</div>
	<div id="c3" name="c3name">c3text</div>
</div>

<script type="text/javascript">
// DocumentFragmentを作成する
let frag = document.createDocumentFragment();

// 子ノードを作成する
let c4 = document.createElement('c4');
let c5 = document.createElement('c5');
let c6 = document.createElement('c6');

frag.append(c4);
frag.append(c5);
frag.append(c6);

console.log(frag);

</script>

</body>
</html>

サーバ上のHTMLはこちら(test2.html)

出力結果は以下のようになります。

DocumentFragment(3) [ c4, c5, c6 ]
​
baseURI: "https://propansystem.net/blogsample/js/040/test2.html"
​
childElementCount: 3
​
childNodes: NodeList(3) [ c4, c5, c6 ]
​
children: HTMLCollection { 0: c4, 1: c5, length: 3, … }
​
firstChild: <c4>
​
firstElementChild: <c4>
​
isConnected: false
​
lastChild: <c6>
​
lastElementChild: <c6>
​
nextSibling: null
​
nodeName: "#document-fragment"
​
nodeType: 11
​
nodeValue: null
​
ownerDocument: HTMLDocument https://propansystem.net/blogsample/js/040/test2.html
​
parentElement: null
​
parentNode: null
​
previousSibling: null
​
textContent: ""
​
<prototype>: DocumentFragmentPrototype { getElementById: getElementById(), querySelector: querySelector(), querySelectorAll: querySelectorAll(), … }

ここでは、DocumentFragmentノードに対して、c4、c5、c6の子ノードが追加されたことがわかります。

では次にDocumentFragmentを他のノードに追加してみます。
先ほどの例のHTMLを使い、「p1」のノードに対して、fragを追加してみます。

<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="UTF-8">
<title>テストHTML</title>
</head>
<body>

<div id="p1" name="p1name">
	<div id="c1" name="c1name">c1text</div>
	<div id="c2" name="c2name">c2text</div>
	<div id="c3" name="c3name">c3text</div>
</div>

<script type="text/javascript">
// DocumentFragmentを作成する
let frag = document.createDocumentFragment();

// 子ノードを作成する
let c4 = document.createElement('div');
let c5 = document.createElement('div');
let c6 = document.createElement('div');

// 作成した子ノードに、HTMLタグとテキストをセットする
c4.appendChild(document.createTextNode('c4text'));
c5.appendChild(document.createTextNode('c5text'));
c6.appendChild(document.createTextNode('c6text'));

frag.append(c4);
frag.append(c5);
frag.append(c6);

console.log(frag);

// Elementノードを取得
let p1 = document.getElementById("p1");

// p1のノードにDocumentFragmentを追加する
p1.append(frag);

</script>

</body>
</html>

サーバ上のHTMLはこちら(test3.html)

出力結果についてですが、まず、console.logは以下のようになります。

DocumentFragment(3) [ div, div, div ]
​
baseURI: "https://propansystem.net/blogsample/js/040/test3.html"
​
childElementCount: 0
​
childNodes: NodeList []
​
children: HTMLCollection { length: 0 }
​
firstChild: null
​
firstElementChild: null
​
isConnected: false
​
lastChild: null
​
lastElementChild: null
​
nextSibling: null
​
nodeName: "#document-fragment"
​
nodeType: 11
​
nodeValue: null
​
ownerDocument: HTMLDocument https://propansystem.net/blogsample/js/040/test3.html
​
parentElement: null
​
parentNode: null
​
previousSibling: null
​
textContent: ""
​
<prototype>: DocumentFragmentPrototype { getElementById: getElementById(), querySelector: querySelector(), querySelectorAll: querySelectorAll(), … }

次に、画面上のHTMLソースは以下のようになります。(bodyタグ内だけの抜粋です)

<div id="p1" name="p1name">
	<div id="c1" name="c1name">c1text</div>
	<div id="c2" name="c2name">c2text</div>
	<div id="c3" name="c3name">c3text</div>
	<div>c4text</div>
	<div>c5text</div>
	<div>c6text</div>
</div>

どうゆう動作になったかというと、上の結果からもわかるとおり、
DocumentFragmentノードそのものは、元のp1の親ノードには影響を及ぼさず、もともとp1が持っていた
子ノードにも影響を及ぼさずに、DocumentFragmentにappendした子ノード「c4」「c5」「c6」だけがp1のノードに追加されています。

上記のような動きをするので、DocumentFragmentは一時的なDOMツリーを生成し、
そこに子ノードを追加してひとまとめにして、他の親ノードに対してまとめた子ノードを追加する。
といった場面で使えると言えます。

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です