【JavaScript】HTMLタグ内の文字列を変更する方法|textContent・innerHTML・innerTextの使い分けとXSS対策

フォーム送信後のメッセージ表示や、ボタン操作に応じた表示更新など、JavaScriptでHTML要素内のテキストを動的に変更する場面はよくあります。

手順は「①要素を取得 → ②textContentinnerHTML で中身を書き換える」だけです。ただし どのプロパティを使うかで安全性や挙動が変わるため、使い分けが重要です。要素の取得はgetElementByIdquerySelectorを使います。

この記事の結論:テキストだけ変えるなら安全な textContent、HTMLタグごと変えるなら innerHTML(ただしユーザー入力を入れるとXSSの危険)。見た目どおりのテキストを扱いたいときだけ innerText を使います。
スポンサーリンク

textContent でテキストを変更する(推奨・安全)

もっとも基本かつ安全な方法です。textContent に文字列を代入すると、HTMLタグもただの文字として表示されるため、意図しないタグ解釈やXSSが起きません。

textContent で変更
// <div id="msg">こんにちは</div>
const el = document.getElementById("msg");

el.textContent = "送信が完了しました";
// → <div id="msg">送信が完了しました</div>

// HTMLを含む文字列も「文字」として表示される(タグ解釈されない)
el.textContent = "<b>太字にならない</b>";
// → 画面には <b>太字にならない</b> がそのまま表示される

innerHTML でHTMLごと変更する(XSS注意)

タグを含むHTMLを設定したいときは innerHTML を使います。文字列内のタグがHTMLとして解釈されます。

innerHTML で変更
const el = document.getElementById("msg");

el.innerHTML = "<strong>完了</strong>しました";
// → <strong> が太字として反映される

el.innerHTML = ""; // 中身を空にする
XSSに注意:el.innerHTML = userInput のようにユーザー入力をそのまま innerHTML に入れると、<script>onerror などが実行される危険(XSS)があります。ユーザー由来の文字列は textContent を使うか、HTMLエスケープしてから入れてください。
innerHTML 経由で挿入した <script> タグは実行されません。動的にスクリプトを追加したい場合は document.createElement("script") で要素を作り appendChild します。

innerText との違い

innerText も似ていますが、「画面に見えているテキスト」を扱う点が異なります。display:none の要素は無視され、参照・代入時にレイアウト計算(リフロー)が走るためtextContent より重くなります。

textContent と innerText の違い
// <div id="box">見える<span style="display:none">隠し</span></div>

const el = document.getElementById("box");

console.log(el.textContent); // "見える隠し"(非表示も含む・生のテキスト)
console.log(el.innerText);   // "見える"(表示されている分だけ)

3つのプロパティの比較

プロパティ HTMLタグ 非表示要素 速度/安全性
textContent 文字として扱う 含む 高速・安全(推奨)
innerHTML HTMLとして解釈 含む XSSに注意
innerText 文字として扱う 含まない リフローで遅め
使い分け:基本は textContent。タグ込みで差し込む必要があるときだけ innerHTML(XSS対策必須)。innerText は「見えている文字そのまま」が必要な特殊ケースに限定します。

特定の要素・複数の要素をまとめて変更する

querySelector でタグ・クラスを指定して要素を絞り込み、複数なら querySelectorAllforEach で一括変更できます。

クラス指定・複数一括
// クラスで1つ取得して変更
document.querySelector(".title").textContent = "新しいタイトル";

// 複数の要素をまとめて変更
document.querySelectorAll(".item").forEach((el, i) => {
  el.textContent = `項目 ${i + 1}`;
});

置き換えずに末尾へ追記する

既存の内容を消さずに追加したいときは、insertAdjacentHTML(HTML)や append(テキスト/ノード)を使います。innerHTML += ... は既存ノードを作り直すため非推奨です。

追記する
const list = document.getElementById("list");

// HTMLを末尾に追加(既存はそのまま)
list.insertAdjacentHTML("beforeend", "<li>新しい項目</li>");

// テキスト/ノードを末尾に追加(XSSの心配がない)
list.append("追記テキスト");

実用例:送信完了メッセージの表示

フォーム送信後のメッセージ
const form = document.getElementById("form");
const result = document.getElementById("result");

form.addEventListener("submit", (e) => {
  e.preventDefault();
  // ユーザー名はユーザー入力なので textContent で安全に表示
  const name = document.getElementById("name").value;
  result.textContent = `${name} さん、送信が完了しました`;
});

よくある質問(FAQ)

QtextContent と innerHTML はどちらを使うべきですか?
Aテキストだけ変えるなら textContent(安全・高速)が基本です。タグを含むHTMLを差し込む必要があるときだけ innerHTML を使い、ユーザー入力を含む場合はXSS対策(textContentかエスケープ)を必ず行ってください。
QinnerHTML にユーザー入力を入れても大丈夫ですか?
A危険です。<img src=x onerror=...> のような文字列でスクリプトが実行されるXSSの原因になります。ユーザー由来の文字列は textContent を使うか、HTMLエスケープしてから挿入してください。
QtextContent と innerText の違いは?
AtextContent生のテキスト全体(非表示要素も含む)を扱い高速です。innerText画面に見えているテキストだけを扱い、レイアウト計算(リフロー)が走るぶん遅くなります。通常は textContent で十分です。
Q複数の要素のテキストをまとめて変えるには?
Adocument.querySelectorAll(セレクタ).forEach(el => el.textContent = "...") のように、querySelectorAll で取得した要素を forEach で回して変更します。

まとめ

JavaScriptでHTML要素内のテキストを変更する方法のポイントを整理します。

  • 手順は「要素を取得 → textContent / innerHTML に代入」
  • テキストだけなら textContent(安全・推奨)
  • タグ込みは innerHTMLユーザー入力はXSS対策必須
  • innerText は「見えているテキスト」用。リフローで遅め
  • 追記は insertAdjacentHTML / appendinnerHTML += は非推奨)

関連として、指定したIDで要素を取得する方法querySelectorでDOM要素を取得する方法HTML要素を追加・削除する方法もあわせて確認すると、DOM操作に強くなれます。