DESIGN / CODE / INFRA / AI

解説

文字を表示したいならtextContent:HTMLとして扱うinnerHTMLとの違いを試そう

入力した山かっこがタグになるのか、文字のまま出るのかを比較。入力値を文字として扱う小さな作例と、HTMLを組み立てる別の方法を紹介するよ。

文字を表示したいならtextContent:HTMLとして扱うinnerHTMLとの違いを試そう

利用者が入力した文章を、ページへそのまま表示したい。そんなときに、文字列をHTMLとして解釈させる必要はあるだろうか? 今回は、文字を入れるtextContentと、HTMLとして扱うinnerHTMLを分けて考えよう。

JavaScriptで要素を取得する基本を知っている人向け。作例の入力はブラウザ内で表示するだけで、送信や保存を行わないよ。

textContentは、文字として設定する

const output = document.querySelector('#output');
output.textContent = '<strong>こんにちは</strong>';

この場合、画面には山かっことstrongを含む文字がそのまま出る。strong要素を作って太字にする処理ではない。入力された文章を、HTMLではなく文字として表示したい場面に使えるよ。

また、textContentへ設定すると、その要素の既存の子要素は文字へ置き換えられる。装飾やほかの部品を残したい場所へ、何でもまとめて設定しないようにしよう。

innerHTMLは、HTMLとして解析する

// 開発者が固定で用意した、確認済みの文字列の例
output.innerHTML = '<strong>こんにちは</strong>';

こちらは文字列がHTMLとして扱われ、strong要素が作られる。用途が違うので、textContentでタグが文字として出たからといって、すぐinnerHTMLへ置き換えないでね。

特に、利用者の入力や外部データのように信頼できない値を、そのままinnerHTMLへ渡すのは危険になり得る。HTMLを受け付ける要件があるなら、許可する内容や安全な処理を別に設計する必要があるよ。

作例では、入力をHTMLとして実行しない

  1. 入力欄には、最初に<strong>こんにちは</strong>が入っている。
  2. 「文字として表示する」を押す。出力欄には、タグのような部分も文字として出る。
  3. 入力を<em>練習</em>へ変えて押す。同じように文字として表示される。
  4. 下の固定サンプルは、開発者が用意したstrongのHTMLとして表示されている。上の入力を反映する場所ではない。

編集部では、自由入力側にstrongやemの子要素が作られず、入力と同じ文字列になること、固定サンプルにはstrong要素があることをChromiumで確認した。任意の入力をHTMLとして実行する切り替えは用意していないよ。「最初から試す」で初期値へ戻せる。

部品を作りたいなら、要素と文字を別にする

const strong = document.createElement('strong');
strong.textContent = userText;
output.replaceChildren(strong);

ここでは、作りたい要素をコード側で指定し、中へ入れる値は文字として扱っている。文字列全体をHTMLとして解析する必要がない場合の、一つの組み立て方だよ。

ただし、URLやスタイル、ほかの属性へ値を入れる処理は、別の条件を持つ。textContentを使っただけで、アプリ全体のすべての入力が安全になるとは考えないでね。

見た目ではなく、DOMも確認する

DOMは、HTMLの要素などをブラウザ内で扱う文書の構造。

文字が太く見えたかだけではなく、開発者ツールなどで、どの要素が実際に作られたかを見ると違いが分かる。入力に山かっこが含まれる場合も、想定した扱いか確認しよう。

HTMLの役割はHTML・CSS・JavaScriptの基礎、表示内容の構造は見出しと太字の違いともつながるよ。

動かしてみよう:入力した文字をそのまま表示する

山かっこを含む文字が、要素になるか文字になるかを比べよう。自由入力はHTMLとして実行しないよ。

参考・出典

みんなのコメント 0

感想や、試してみたことを聞かせてね。コメント・返信は承認後に公開されます。

最初のコメントをどうぞ。