テキストを書き換える
このレッスンで分かること
textContentで表示されている文字を差し替える書き方innerHTMLとの違いと、それが危ない理由innerTextを含めた 3 つの使い分け
テキストを書き換える とは
掴んだ要素の中の文字を JavaScript から差し替える操作です。プロフィールサイトの肩書きや見出しが、ページを開いた瞬間に書きかわります。
掴んだら、代入するだけ
前回は要素を掴んで印を付けました。今回はその要素の中の文字を変えます。書き方は拍子抜けするほど短く、プロパティに代入するだけです。
const tagline = document.querySelector(".tagline");
tagline.textContent = "JavaScript も学びはじめました";これだけで、画面の肩書きが差し替わります。第2章でやった変数への代入と同じ書き方です。左辺が変数ではなく要素のプロパティになっているだけで、= の意味は変わりません。
読むこともできます。代入せずに右辺として使えば、いま表示されている文字が取れます。
const tagline = document.querySelector(".tagline");
console.log(tagline.textContent); // "Web エンジニアを目指しています"
tagline.textContent = tagline.textContent + " (更新中)";textContent はその要素の中にある文字をすべてつなげたものです。子要素の中の文字も含まれます。自己紹介の段落には span や strong が入っていますが、textContent で読むとタグは消えて、文字だけが 1 本につながって返ります。
代入すると、中に入っていた子要素はまるごと消えます。
profile-textのtextContentに文字を代入すると、中のspan.highlightもstrongも無くなり、代入した文字だけが残ります。中の一部だけを変えたいときは、その一部を先に掴んでから代入します。
textContent と innerHTML と innerText
似たものが 3 つあります。違いは「タグとして読むか」「見た目を考えるか」の 2 点です。
| プロパティ | 代入した文字列 | 読み出すもの | 速さ |
|---|---|---|---|
textContent | ただの文字として入る | 隠れている文字も含む全部 | 速い |
innerHTML | タグとして解釈される | 中の HTML がそのまま文字列で返る | 遅い |
innerText | ただの文字として入る | 画面に見えている文字だけ | 遅い |
innerHTML に "<strong>やあ</strong>" を入れると、本当に太字の要素ができます。便利そうに見えますが、この便利さがそのまま危なさになります。
const el = document.querySelector(".tagline");
el.textContent = "<strong>やあ</strong>"; // 画面に <strong>やあ</strong> と出る
el.innerHTML = "<strong>やあ</strong>"; // 画面に 太字の やあ と出る読み出したときの違いも見ておきます。自己紹介の段落には span と strong が入っています。同じ要素から読んでも、返ってくるものはこれだけ変わります。
const p = document.querySelector(".profile-text");
p.textContent; // "こんにちは。山田 太郎です。2026 年から HTML と CSS を…"
p.innerHTML; // "こんにちは。<span class=\"highlight\">山田 太郎</span>です。…"textContent はタグを取り払った文字だけ、innerHTML はタグごと文字列にして返します。中に何が入っているかを調べたいときは innerHTML が役に立ちますが、書き込みに使うと話が変わります。
innerText は画面に見えているものだけを返します。display: none で隠した部分は無視されますし、改行も見た目どおりに入ります。そのぶん、読み出すたびにブラウザがレイアウトを計算し直すので遅くなります。表示の見た目をそのまま文字にしたい、という特別な用事がないかぎり出番はありません。
innerHTML が危ない理由
innerHTML は、渡された文字列を HTML として解釈します。ここに外から来た文字列を入れると、その人が書いたタグがページの一部になります。
// お問い合わせフォームに入力された文字を、そのまま画面に出したいとする
const message = form.message.value;
preview.innerHTML = message; // 危ないもし入力欄に <img src="x" onerror="..."> と書かれていたら、画像の読み込みに失敗した瞬間に onerror の中身が実行されます。ページを見ている人の名前でクッキーを盗んだり、勝手に投稿したりできてしまいます。これをクロスサイトスクリプティング (XSS) と呼びます。Web アプリのぜい弱性としてもっとも古くからあり、いまも減っていません。
対策はむずかしくありません。文字を出したいときは textContent を使う。それだけです。textContent に何を渡しても、それは文字として表示されるだけで、タグにはなりません。
preview.textContent = message; // 安全。タグが書かれても文字として出るこのコースでは、文字を入れるときは必ず
textContentを使います。innerHTMLは「自分で書いた固定の文字列を入れるとき」だけに限れば安全ですが、そういう場面は次の回で学ぶcreateElementでも書けます。危ないほうの道具を最初から手に取らない、という決め方をしておくと事故が起きません。
今回書きかえるもの
プロフィールサイトの 3 か所を JavaScript から書きかえます。前回のコードはそのまま残し、下に足していきます。
- 肩書き
.taglineを「JavaScript も学びはじめました」にする - 作品セクションの見出し
#works .section-titleを「作品ギャラリー」にする - フッターの著作権表示
.site-footer pを「(c) 2026 山田 太郎 / JavaScript で更新」にする
2 番目のセレクタに注目してください。.section-title はページ上に 6 つあります。querySelector(".section-title") では自己紹介の見出しが返ってしまうので、#works の中に絞り込みます。CSS で子孫セレクタを書いたときと同じ考え方です。
const worksTitle = document.querySelector("#works .section-title");
worksTitle.textContent = "作品ギャラリー";プレビューを見ると、HTML には「作品」と書いてあるのに、画面には「作品ギャラリー」と出ます。DOM が書きかわったからです。検証ツールの Elements タブで確かめると、h2 の中身が変わっているのが見えます。
3 番目のフッターも同じ考え方です。.site-footer の中には p が 1 つしかないので、.site-footer p で狙えます。もとの HTML には © という実体参照が書いてありますが、textContent に代入するときは (c) のようなただの文字を渡します。© という 6 文字をそのまま渡すと、記号にはならずに © と表示されてしまいます。実体参照を解釈するのは HTML のパーサーの仕事で、textContent はそこを通らないからです。
なお、前回書いた setAttribute の行は消さないでください。この章のコードは回を追うごとに下へ足していき、最後の回で 1 本のまとまったスクリプトになります。
よくある間違い
textContent を関数として呼ぶ
textContent はプロパティです。丸かっこは付けません。
el.textContent("こんにちは"); // TypeError
el.textContent = "こんにちは"; // 正しい代入したあとに子要素を掴もうとする
textContent への代入で中身は消えます。順番を間違えると、掴めるはずのものが null になります。
const p = document.querySelector(".profile-text");
p.textContent = "書きかえました";
const span = p.querySelector(".highlight"); // もう無いので null数値をそのまま入れて驚く
textContent に数値を入れると、自動で文字列に変わって表示されます。エラーにはなりませんが、0 を入れたときに空欄に見えてしまうことがあります。単位や説明を足して "0 回表示" のように渡すと、意図が伝わる表示になります。
課題
.taglineのtextContentを"JavaScript も学びはじめました"にする#works .section-titleを掴み、textContentを"作品ギャラリー"にする.site-footer pを掴み、textContentを"(c) 2026 山田 太郎 / JavaScript で更新"にする- 文字を入れるのは
textContentだけを使い、innerHTMLは使わない