Element
オブジェクトの innerHTML
プロパティは、要素内の HTML または XML のマークアップを取得したり設定したりします。
<div>
, <span>
, <noembed>
ノードが (&)
, (<)
, (>)
の文字を含むテキストの子ノードを持っている場合、 innerHTML
はこれらの文字を HTML エンティティの "&"
, "<"
, ">"
としてそれぞれ返します。これらのテキストノードの内容の生のコピーを取得するには 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 エンティティの "<"
に置き換え、それによって本質的に HTML を生テキストに変換します。そしてこれを <pre>
で囲みます。そして、 innerHTML
の値をこの新しい文字列に変更します。結果として、文書の内容がページ全体のソースコードの表示に置き換わります。
document.documentElement.innerHTML = "<pre>" +
document.documentElement.innerHTML.replace(/</g,"<") +
"</pre>";
Operational details
innerHTML
に値を設定すると、正確には何が起きるのでしょうか?これを行うと、ユーザーエージェントは以下のステップを追います。
- 指定された値は (文書型に基づいて) HTML または XML として解釈され、新しい一連の要素の DOM ノードを表す
DocumentFragment
オブジェクトの中に結果が入れられます。 - 中身を置き換えようとしている要素が
<template>
要素である場合は、<template>
要素のcontent
属性を、ステップ1で生成された新しいDocumentFragment
で置き換えます。 - その他の要素はすべて、要素の内容を新しい
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
このページの互換性一覧表は構造化データから生成されています。データに協力していただけるのであれば、 https://github.com/mdn/browser-compat-data をチェックアウトしてプルリクエストを送信してください。
関連情報
Node.textContent
およびNode.innerText
Element.insertAdjacentHTML()
- HTML を解析して DOM ツリーへ入れる:
DOMParser
- XML または HTML をシリアライズして DOM ツリーへ入れる:
XMLSerializer