JavaScriptでHTML要素を追加したい
動的にHTML要素を追加したい時など、JavaScriptでHTMLをいじくりたいなぁというときは
insertAdjacentHTML
を使います。
このinsertAdjacentHTML
と同じようなことができるinnerHTML
というものがあります。
どっちが良いの? 違いは? ということで調べてみました。
insertAdjacentHTML を使おう
結論から言うと、insertAdjacentHTML
を使う方が良い。
insertAdjacentHTML
insertAdjacentHTML() は、第二引数で指定するテキストを HTML または XML としてパースし、
その結果であるノードを DOM ツリー内の指定された位置(第一引数で指定)に挿入します。
これは挿入先の要素を再度パースするものではないため、既存の要素や要素内部の破壊を伴いません。
余分なシリアル化のステップを回避できる分、 innerHTML への代入による直接的な操作よりもはるかに高速な動作となります。
innerHTML
Element オブジェクトの innerHTML プロパティは、要素内の HTML または XML のマークアップを取得したり設定したりします。
要素の内容を置き換えるというより、文書に HTML を挿入するという場合には、 insertAdjacentHTML() メソッドを使用してください。
insertAdjacentHTML
が良いんだろうなと言うことはバシバシ伝ってきます。
既存の要素や要素内部の破壊!?
破壊という恐ろしいワードが気になる方のために簡単なサンプルを用意してみました。
<html>
<body>
<div id="container">
<button id="button">クリック!</button>
</div>
</body>
</html>
<script>
const button = document.getElementById('button');
button.addEventListener('click', function () {
const container = document.getElementById('container');
container.innerHTML = '<div>ボタンをクリックしました</div>' + container.innerHTML;
});
</script>
- 「クリック!」ボタンを表示
- JavaScriptで
innerHTML
を使ってボタンの前に「ボタンをクリックしました」と表示するイベントを追加
少し強引な例ですが、ボタンを2回目以降はボタンをクリックしても
「ボタンをクリックしました」が表示されることはありません。
破壊手順(クリックイベント内の処理)の解説
1. #container
内の要素をgetElementById
で取得
2. #container
内の要素である#button
をinnerHTML
でHTML文字列として取得してbuttonHtml変数に格納
3. #container
内の要素を<div>ボタンをクリックしました</div>
とbuttonHtmlを結合してinnerHTML
で書き換える
4. 「クリック!」ボタンは新しいボタン要素として描画されている
5. addEventListener
は初回の画面表示にしか走らないのでクリックイベントが追加されることはない
※2.がないとボタンが消えてしまいます
insertAdjacentHTMLで実装してみる
<html>
<body>
<div id="container">
<button id="button">クリック!</button>
</div>
</body>
</html>
<script>
const button = document.getElementById('button');
button.addEventListener('click', function () {
container.insertAdjacentHTML('afterbegin', '<div>ボタンをクリックしました</div>');
});
</script>
ボタンをクリックする度に「ボタンをクリックしました」が表示されるようになります。
insertAdjacentHTML
は第一引数にposition
があります。
element.insertAdjacentHTML(position, text);
- beforebegin:
element
の直前に挿入 - afterbegin:
element
内部の、最初の子要素の前に挿入 - beforeend:
element
内部の、最後の子要素の後に挿入 - afterend:
element
の直後に挿入
<html>
<body>
<!-- 1. beforebegin -->
<div id="container">
<!-- 2. afterbegin -->
<button id="button">クリック!</button>
<!-- 3. beforeend -->
</div>
<!-- 4. afterend -->
</body>
</html>
insertAdjacentHTMLは高速
今回参考にした記事では実際に計測されていました。
10倍近い差が出たそうですが、記事のコメントにはブラウザによって差異があるとの報告もありました。
innerHTML より insertAdjacentHTML を使う
最後に
HTMLの大部分を書き換える際はinnerHTML
でも良いのかも知れませんが
そのようなケースは稀でしょうから、insertAdjacentHTML
を使うと言う認識で問題ないのかと思います。
また、HTML要素を追加したいという目的であれば、insertAdjacentHTML
ではなく
Document.createElement()やNode.appendChildを使うという実装も考えられます。
そのときどきに合ったベストな方法で実装するしかない、というところでしょうか。
おしまい。