吉本集の個人ブログ
Web制作の技術について書いています。たまに日記も書きます。

【JS入門】DOMについて Vol.3(ノードの値の参照・変更)

2018年2月5日 / category : javascript

前回の記事「DOMについて Vol.2(ノードの参照・取得)」では、ノードの参照・取得について解説しました。今回は取得したノードの値の参照・変更について解説します。

ノードの値の参照・変更

ノードの値を参照・変更するためには、Nodeインターフェースで定義されているプロパティinnerText、outerTextがあり、Elementインターフェースで定義されているプロパティinnerHTML、outerHTMLがあります。それぞれの違いを含め解説します。

Node.innerText:ノードの値を参照します。参照する際はHTML要素は含まないが、変更する際はHTML要素を含む。
構文

let text = Node.innerText;
Node.innerText = text;

次のコードを見てみます。

index.html
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="UTF-8">
<title>タイトル</title>
</head>
<body>
<div>
<h1>見出し</h1>
<p id="txt"><span>お腹減った。</span></p>
</div>
<script src="./js/sample.js"></script>
</body>
</html>
sample.js
console.log( document.getElementById('txt').innerText ); // お腹減った。
console.log( document.getElementById('txt').innerHTML ); // <span>お腹減った。</span>
document.getElementById('txt').innerText = 'お腹減っていない。';
console.log( document.getElementById('txt').innerText ); // お腹減っていない。
console.log( document.getElementById('txt').innerHTML ); // お腹減っていない。

id属性にtxtが設定されているp要素のプロパティinnerTextを見ると「お腹減った。」が参照されました。p要素内にあるspan要素は参照対象になっていません。プロパティinnerHTMLは、後ほど解説しますが、HTML要素を含んで参照します。そのためspan要素を含めた要素を参照しています。「お腹減っていない。」をプロパティinnerTextに代入後、再度プロパティinnerHTMLを参照するとspan要素がなくなっています。これは変更する際はHTML要素を含んだ要素が対象になると言えます。

Node.innerTextの参照

Node.innerTextを変更

Node.outerText:ノードの値(自身の要素を含む)を参照します。参照する際はHTML要素は含まないが、変更する際はHTML要素を含む。
構文

let text = Node.outerText;
Node.outerText = text;

sample.js
console.log( document.getElementById('txt').outerText ); // お腹減った。
console.log( document.getElementById('txt').innerHTML ); // <span>お腹減った。</span>
document.getElementById('txt').outerText = 'お腹減っていない。';
console.log( document.getElementById('txt').outerText ); // TypeError: Cannot read property 'outerHTML' of null
console.log( document.getElementById('txt').innerHTML ); // TypeError: Cannot read property 'innerHTML' of null

プロパティouterTextは、自身の要素(タグ)を含みます。ただし、参照する際はHTML要素を含みませんので、参照結果はプロパティinnerTextと同様の結果になります。変更する際は自身の要素(タグ)を含めたHTML要素も参照対象になるため、次の図のように自身の要素が全て「お腹減っていない。」のテキストデータに差し変わります。そのため変更後のプロパティouterHTML、innerHTMLを参照すると自身がnullになってしまったため参照することができないというエラーになります。
また、プロパティouterTextはFirefoxでサポートされていないため使用することが推奨できません。

Node.outerTextの参照

Node.outerTextを変更

Element.innerHTML:ノードの値を参照します。HTML要素を含む。
構文

let text = Element.innerHTML;
Element.innerHTML = text;

sample.js
console.log( document.getElementById('txt').innerHTML ); // <span>お腹減った。</span>
document.getElementById('txt').innerHTML = 'お腹減っていない。';
console.log( document.getElementById('txt').innerHTML ); // お腹減っていない。

プロパティinnerTextとは異なり、参照する際もHTML要素を含みますので、p要素内にあるspan要素も参照対象に入ります。

Element.innerHTMLの参照

Element.innerHTMLを変更

Element.outerHTML:ノードの値(自身の要素を含む)を参照します。HTML要素を含む。
構文

let text = Element.outerHTML;
Element.outerHTML = text;

sample.js
console.log( document.getElementById('txt').outerHTML ); // <p id="txt"><span>お腹減った。</span></p>
document.getElementById('txt').outerHTML = 'お腹減っていない。';
console.log( document.getElementById('txt').outerHTML ); // TypeError: Cannot read property 'outerHTML' of null

プロパティouterHTMLもプロパティinnerHTMLと同様に参照する際もHTML要素を含みます。プロパティouterHTMLは自身の要素(タグ)も含みますので、p要素から参照することになります。テキストデータの代入後、エラーになってしまうのは、プロパティouterTextと同じ現象です。

Element.outerHTMLの参照

Element.outerHTMLを変更

これら4つのプロパティをまとめたのが次の図です。

Node.textContentによる値の参照・変更

上で紹介した4つのプロパティ以外に、Nodeインターフェースが持つプロパティtextContentを使用することで値を参照・変更することができます。

Node.textContent:ノードの値を参照します。HTML要素は含まない。
構文

let text = Node.textContent;
Node.textContent = text;

プロパティtextContentはHTML要素を含まないため、上で紹介したプロパティinnerHTMLとは使い分けができます。プロパティinnerTextとの違いを見てみます。

sample.js
let html = document.documentElement;

let content = html.textContent;
console.log( content );

let inner = html.innerText;
console.log( inner );

変数contentのコンソール結果

タイトル
見出し
お腹減った。

変数innerのコンソール結果

見出し
お腹減った。

ノードの対象はhtml要素です。html要素から参照する値は、プロパティtextContentの場合はtitle要素を含むテキストデータを参照しています。プロパティinnerTextはブラウザの表示部分となる要素のテキストデータを参照しています。変更する仕様は、プロパティinnerTextと同様です。
プロパティinnerTextとのもうひとつ違いですが、次のコードを見てみます。

index.html
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="UTF-8">
<title>タイトル</title>
</head>
<body>
<div>
<p id="txt">
お
腹
減
っ
た
。
</p>
</div>
<script src="./js/sample.js"></script>
</body>
</html>
sample.js
let txt = document.getElementById('txt');
console.log( txt.textContent );
console.log( txt.innerText );

txt.textContentのコンソール結果







txt.innerTextのコンソール結果

お 腹 減 っ た 。

上の結果から分かるように、プロパティtextContentはコードをそのまま出力します。

テキストノードの値の参照・変更

テキストデータのみを変更するのであれば、Nodeインターフェースで定義されているプロパティnodeValueを使用することを推奨します。プロパティtextContentと比較して処理速度が速いためです。

Node.nodeValue:テキストノードの値を参照・変更する。
構文

let text = Node.nodeValue;
Node.nodeValue = text;

次のコードを見てみます。

index.html
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="UTF-8">
<title>タイトル</title>
</head>
<body>
<div>
<h1>見出し</h1>
<p id="txt">お腹減った。</p>
</div>
<script src="./js/sample.js"></script>
</body>
</html>
sample.js
console.log( document.getElementById('txt').nodeValue ); // null

上のコードで「お腹減った。」のテキストデータを参照したかったのですが、nullが返ってきてしまいました。これは意図した結果ではありません。プロパティnodeValueはテキストノードの値を参照します。前回の記事「DOMについて Vol.2(ノードの参照・取得)」の中でTextインターフェースを継承したオブジェクトという解説で出てきたオブジェクトがテキストノードになります。

sample.js
let p = document.getElementById('txt');
let txt = p.firstChild;
console.log( txt ); // "お腹減った。"
console.log( typeof txt ); // object

上のようなコードでテキストノードが参照できます。変数pはp要素(ノード)を参照していますが、p要素の中の最初のノードが「お腹減った。」というテキストノードとなります。一見テキストデータに見えますが、typeof演算子で型を調べるとobjectが返ってきています。次のようにプロパティchildNodesでもテキストノードを参照することができます。

sample.js
let p = document.getElementById('txt');
let txt = p.childNodes[0];
console.log( txt ); // "お腹減った。"
console.log( typeof txt ); // object

プロパティchildNodesでp要素(ノード)の中にある全てのノードを返します。そのノードの最初のノードが「お腹減った。」というテキストノードとなります。それではこのテキストノードにプロパティnodeValueを使用してみます。

sample.js
let p = document.getElementById('txt');
let txt = p.firstChild;
console.log( txt.nodeValue ); // お腹減った。

問題なく「お腹減った。」が参照できました。続いて、プロパティnodeValueを使用して別のテキストデータを代入してみます。

sample.js
let p = document.getElementById('txt');
let txt = p.firstChild;
txt.nodeValue = 'お腹減っていない。';

ブラウザの表示を見ると問題なくテキストが変わっています。テキストデータを変更する場合は、プロパティnodeValueを使用して変更することを推奨します。