element.innerHTML

Element オブジェクトの innerHTML プロパティは、要素内の HTML または XML のマークアップを取得したり設定したりします。

メモ: <div>, <span>, <noembed> ノードが (&), (<), (>) の文字を含むテキストの子ノードを持っている場合、 innerHTML はこれらの文字を HTML エンティティの "&amp;", "&lt;", "&gt;" としてそれぞれ返します。これらのテキストノードの内容の生のコピーを取得するには Node.textContent を使用してください。

要素の内容を置き換えるというより、文書に HTML を挿入するという場合には、 insertAdjacentHTML() メソッドを使用してください。

構文

const content = element.innerHTML;

element.innerHTML = htmlString;

要素の子孫を HTML シリアライズしたものを含んだ DOMString です。 innerHTML に値を設定すると、要素のすべての子孫を削除して、 htmlString の文字列で与えられた HTML を解析して構築されたノードに置き換えます。

例外

SyntaxError
正しくない形の HTML の文字列を使用して innerHTML の値を設定しようとした場合。
NoModificationAllowedError
親が Document であるノードに HTML を挿入しようとした場合。

使用上のメモ

innerHTML プロパティは、ページの現在の HTML ソースを、ページが最初に読み込まれてから行われたあらゆる変更を含めて、見るために利用することができます。

要素の HTML コンテンツの読み取り

innerHTML を読み取ると、ユーザーエージェントが要素の子孫で構成される HTML または XML の断片をシリアライズします。結果として文字列が返ります。

let contents = myElement.innerHTML;

これで、 HTML のコンテンツのノードの HTML マークアップを見ることができます。

メモ: 返される HTML または XML の断片は、現在の要素の中身に基づいて生成されますので、返される断片のマークアップや整形方法は、元のページのマークアップと同じであるとは限りません。

要素の中身の置き換え

innerHTML の値を設定することで、既存の要素の内容を新しい内容に置き換えることが簡単にできます。

例えば、文書の body 属性の内容を消去することで、文書の内容全体を消去することができます。

document.body.innerHTML = "";

この例は文書の現在の HTML マークアップを走査し、 "<" の文字を HTML エンティティの "&lt;" に置き換え、それによって本質的に HTML を生テキストに変換します。そしてこれを <pre> で囲みます。そして、 innerHTML の値をこの新しい文字列に変更します。結果として、文書の内容がページ全体のソースコードの表示に置き換わります。

document.documentElement.innerHTML = "<pre>" +
         document.documentElement.innerHTML.replace(/</g,"&lt;") +
            "</pre>";

Operational details

innerHTML に値を設定すると、正確には何が起きるのでしょうか?これを行うと、ユーザーエージェントは以下のステップを追います。

  1. 指定された値は (文書型に基づいて) HTML または XML として解釈され、新しい一連の要素の DOM ノードを表す DocumentFragment オブジェクトの中に結果が入れられます。
  2. 中身を置き換えようとしている要素が <template> 要素である場合は、 <template> 要素の content 属性を、ステップ1で生成された新しい DocumentFragment で置き換えます。
  3. その他の要素はすべて、要素の内容を新しい DocumentFragment のノードで置き換えます。

セキュリティの考慮事項

ウェブページにテキストを挿入するために innerHTML を使用している例は珍しくありませんありません。これがサイト上の攻撃ベクトルになる可能性があり、潜在的なセキュリティリスクが生じます。

const name = "John";
// 'el' を HTML の DOM 要素と想定します
el.innerHTML = name; // この場合は無害

// ...

name = "<script>alert('I am John in an annoying alert!')</script>";
el.innerHTML = name; // この場合は無害

これはクロスサイトスクリプティング攻撃のように見えますが、結果的には無害です。 HTML5 では innerHTML で挿入された <script> タグは実行するべきではないと定義しているからです。

しかし、次のように <script> を使わずに JavaScript を実行する方法もあるので、制御することができない文字列を設定するために innerHTML を使用するたびに、セキュリティリスクは残ります。

const name = "<img src='x' onerror='alert(1)'>";
el.innerHTML = name; // アラートが表示される

このため、プレーンテキストを挿入するときには innerHTML を使用せず、代わりに Node.textContent を使用することをお勧めします。これは渡されたコンテンツを HTML として解釈するのではなく、生テキストとして挿入します。

警告: プロジェクトに対して何らかの形のセキュリティレビューが行われる場合、 innerHTML は多くの場合、コードが拒絶される結果になります。例えば、ブラウザー拡張機能の中で innerHTML を使用した場合、拡張機能を addons.mozilla.org に提出すると、自動レビュープロセスを通過できないでしょう。

この例は innerHTML を使用して、ウェブページ上のボックス内にメッセージを記録するメカニズムを作成します。

JavaScript

function log(msg) {
  var logElem = document.querySelector(".log");

  var time = new Date();
  var timeStr = time.toLocaleTimeString();
  logElem.innerHTML += timeStr + ": " + msg + "<br/>";
}

log("Logging mouse events inside this container...");

log() 関数は Date オブジェクトから toLocaleTimeString() を使用して現在時刻を取得し、タイムスタンプとメッセージテキストから成る文字列を構築してログ出力を生成します。それから "log" クラスのボックスにメッセージを追加します。

MouseEvent ベースのイベント (mousedown, click, mouseenter など) についての情報を記録する第二のメソッドを追加します。

function logEvent(event) {
  var msg = "Event <strong>" + event.type + "</strong> at <em>" +
            event.clientX + ", " + event.clientY + "</em>";
  log(msg);
}

それから、これをログを収めるボックスの様々なマウスイベントのイベントハンドラーとして登録します。

var boxElem = document.querySelector(".box");

boxElem.addEventListener("mousedown", logEvent);
boxElem.addEventListener("mouseup", logEvent);
boxElem.addEventListener("click", logEvent);
boxElem.addEventListener("mouseenter", logEvent);
boxElem.addEventListener("mouseleave", logEvent);

HTML

この例の HTML はとても単純です。

<div class="box">
  <div><strong>Log:</strong></div>
  <div class="log"></div>
</div>

"box" クラスが付いた <div> は、単なるレイアウト用途のコンテナーであり、内容とその周りのボックスを表します。クラスが "log" である <div> は、ログテキスト自身のコンテナーです。

CSS

以下の CSS が例の内容をスタイル付けします。

.box {
  width: 600px;
  height: 300px;
  border: 1px solid black;
  padding: 2px 4px;
  overflow-y: scroll;
  overflow-x: auto;
}

.log {
  margin-top: 8px;
  font-family: monospace;
}

結果

結果の内容はこのように見えます。マウスが移動してボックスを出入りしたり、中でクリックしたりすると、ログが出力されるのを見ることができます。

仕様書

仕様書 状態 備考
DOM Parsing and Serialization
Element.innerHTML の定義
草案 初回定義

ブラウザーの対応

BCD tables only load in the browser

関連情報