5
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

JavaScript | HTML要素を追加したい時に使うinnerHTMLとinsertAdjacentHTML

Last updated at Posted at 2021-07-23

JavaScriptでHTML要素を追加したい

動的にHTML要素を追加したい時など、JavaScriptでHTMLをいじくりたいなぁというときは
insertAdjacentHTMLを使います。

このinsertAdjacentHTMLと同じようなことができるinnerHTMLというものがあります。

どっちが良いの? 違いは? ということで調べてみました。

insertAdjacentHTML を使おう

結論から言うと、insertAdjacentHTMLを使う方が良い。

insertAdjacentHTML

insertAdjacentHTML() は、第二引数で指定するテキストを HTML または XML としてパースし、
その結果であるノードを DOM ツリー内の指定された位置(第一引数で指定)に挿入します。
これは挿入先の要素を再度パースするものではないため、既存の要素や要素内部の破壊を伴いません。
余分なシリアル化のステップを回避できる分、 innerHTML への代入による直接的な操作よりもはるかに高速な動作となります。

element.insertAdjacentHTML

innerHTML

Element オブジェクトの innerHTML プロパティは、要素内の HTML または XML のマークアップを取得したり設定したりします。
要素の内容を置き換えるというより、文書に HTML を挿入するという場合には、 insertAdjacentHTML() メソッドを使用してください。

Element.innerHTML

insertAdjacentHTMLが良いんだろうなと言うことはバシバシ伝ってきます。

既存の要素や要素内部の破壊!?

破壊という恐ろしいワードが気になる方のために簡単なサンプルを用意してみました。

corruption.html
<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内の要素である#buttoninnerHTMLでHTML文字列として取得してbuttonHtml変数に格納
3. #container内の要素を<div>ボタンをクリックしました</div>とbuttonHtmlを結合してinnerHTMLで書き換える
4. 「クリック!」ボタンは新しいボタン要素として描画されている
5. addEventListenerは初回の画面表示にしか走らないのでクリックイベントが追加されることはない

※2.がないとボタンが消えてしまいます

insertAdjacentHTMLで実装してみる

no_corruption.html
<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);

  1. beforebegin: elementの直前に挿入
  2. afterbegin: element内部の、最初の子要素の前に挿入
  3. beforeend: element内部の、最後の子要素の後に挿入
  4. 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を使うという実装も考えられます。

そのときどきに合ったベストな方法で実装するしかない、というところでしょうか。

おしまい。

5
3
2

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
5
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?