JavaScript

JavaScript textContent property.

textContent

 HTMLファイルの中にはテキストを持っているノードがあり、DOM操作ではノード内のテキストにアクセスする場面も多くあります。

 今回は、textContentプロパティを用いたノードのテキストの取得や書き込み方法について解説していきます。

テキストの取得

 textContentプロパティは、特定のノードに対して、ノード内のテキストを文字列で取得します。


node.textContent;

 戻り値は、対象のテキストが連結されたDOMStringオブジェクトです。ノードの種類によって返ってくるテキストが異なります。

 テキストノードやコメントノードの場合、そのノードの内側のテキストを返します。また、要素ノードやドキュメントノードの場合、すべての子ノード(コメントノードと処理命令ノード以外)のテキストを連結したものを返します。

 各ノードに対するノードのテキストの一覧は以下です。

要素ノード
子ノードのテキストの連結
属性ノード
子ノードのテキストの連結
テキストノード
内側のテキスト
CDATAセクション
内側のテキスト
実体参照
子ノードのテキストの連結
実体宣言
子ノードのテキストの連結
処理命令
内側のテキスト
コメントノード
内側のテキスト
ドキュメントノード
子ノードのテキストの連結
ドキュメントタイプ
子ノードのテキストの連結
ドキュメントの断片
子ノードのテキストの連結
記法
子ノードのテキストの連結

 まずはかんたんな例として、以下の <h1> のテキストを取得してみます。

HTML + JavaScript source


<h1>Hello!</h1>

<script>
	let element = document.querySelector('h1');
	console.log(element.textContent); // "Hello!"
</script>

 <h1> の中にある ”Hello!” というテキストが取得できます。

 今度は、タグを増やして <div> の内側にあるテキストを取得してみます。

HTML + JavaScript source


<div>
	<h1>Hello!</h1>
	<p>My name is JavaScript.</p>
</div>

<script>
	let element = document.querySelector('div');
	console.log(element.textContent); 
	/*
	"
	
		Hello!
		My name is JavaScript.
	
	"
	*/
</script>

 <div>のすべての子ノードのテキストが連結された値が返ります。

 要素ノードを対象とした場合、すべての子ノードのテキストが含まれるため、空白ノードも対象です。

 そのため、”Hello! My name is JavaScript” の前後の空白も含まれるということになります。

テキストの書き込み

 textContentプロパティは、新しいテキストを書き込むこともできます。


node.textContent = 'value';

 以下は、空の <p> に対してテキストを書き込んだ例です。

HTML + JavaScript source


<div>
	<h2>Hello!</h2>
	<p id="sample"></p>
</div>

<script>
	const element = document.getElementById('sample');
	element.textContent = 'My name is JavaScript.';
</script>

Hello!

 <p> の内側に新しく「My name is JavaScript.」と書き込むことができました。

 もし、既に対象のノードがテキストを持っている場合、新しく書き込んだテキストに置き換わります。

Hello!

My name is JavaScript.

 元々テキストを持っている <h2> に対して、新しいテキストを設定すると、「Hello!」から「Hi!」に置き換わることが確認できます。

 また、<h2> が持っているテキストをコンソール出力すると、”Hi!”という値を持っていることが分かります。

 では次に、いくつかの子ノードを持っているノードに対してテキストを書き込んでみましょう。

 <div> を対象に新しくテキストを設定します。

HTML + JavaScript source


<div id="sample3">
	<h2>Hello!</h2>
	<p>My name is JavaScript.</p>
</div>

<script>
	const element3 = document.getElementById('sample3');
	element3.textContent = 'I am learning DOM.';
	
	for (let i = 0; i < element3.childNodes.length; i++) {
		console.log(element3.childNodes[i]);
	}
</script>

Hello!

My name is JavaScript.

 すると、元々あったすべてのテキストが無くなり、新しく書き込んだ「I am learning DOM.」のみが表示されます。

 さらに <div> に対して子ノード検索を行うと、テキストノードのみ持っていることが分かります。

 このことから、textContentによる書き込みは次のことが言えます。

innerHTMLと textContentの違い

 innerHTMLプロパティと textContentプロパティが混同してしまう方もいるかもしれません。

 テキストの書き込みに対してどちらも使用することができますが、機能の根本的な部分が異なります。

innerHTML
要素内のHTMLを返す。
textContent
ノードが持っているテキストを返す。

 2つを比べてみます。

innerHTMLの場合


<div id="sample4">
	<h2>Hello!</h2>
	<p>My name is JavaScript.</p>
</div>

<script>
	const element4 = document.getElementById('sample4');
	console.log(element4.innerHTML);
	/*
	"
		<h2>Hello!</h2>
		<p>My name is JavaScript.</p>
	"
	*/
</script>

Hello!

My name is JavaScript.

textContentの場合


<div id="sample5">
	<h2>Hello!</h2>
	<p>My name is JavaScript.</p>
</div>

<script>
	const element5 = document.getElementById('sample5');
	console.log(element5.textContent);
	/*
	"
		Hello!
		My name is JavaScript.
	"
	*/
</script>

Hello!

My name is JavaScript.

 innerHTMLプロパティはタグなども含まれる HTMLを返すのに対し、textContentプロパティの特徴は純粋にテキストのみを返します。

 特にテキストを書き込むことに注力を当てると、textContentプロパティの方が安全性が高いです。

 例えば、ユーザーから受け取った任意のテキストを表示したい場合を比較してみましょう。

innerHTMLの場合


<div id="sample6"></div>

<script>
	const element6 = document.getElementById('sample6');
	element6.innerHTML = '<h2>Hello World!</h2>';
</script>

 innerHTMLプロパティでは、書き込まれた内容はHTMLとして扱われます。そのため、「Hello, World!」というテキストが見出しとして表示されます。

textContentの場合


<div id="sample6"></div>

<script>
	const element6 = document.getElementById('sample6');
	element6.innerHTML = '<h2>Hello World!</h2>';
</script>

 一方、textContentプロパティでは、書き込まれた内容はすべてテキストとして表示します。そのため <h2> のようなタグもそのままテキストとして表示されます。

 自身の Webサイトにユーザーから受け取ったテキストを表示するような場面では、ユーザーのテキストはそのままテキストとして扱った方が無難です。

 予期せぬ HTMLを Webサイトに影響させないためにも、単純にテキストを扱うような場面では textContextを用いる方が正確に行えます。