・IT/Web系エンジニアの経験者の方
・どこの転職エージェントを利用しようか迷っている方
それなら、キッカケエージェントにご相談!
キッカケエージェントでは、少数精鋭のエージェントが、エンジニアの経験やスキル、志向性などをカウンセリングし、的確なアドバイスを提供します!
また、徹底した企業へのヒアリングにより、最適なマッチングを実現し、今では内定率が一般的なエージェントの2倍以上となっています!
転職エージェントに迷っている方、まずは無料でキャリア相談から!
(この記事は2023年05月18日に投稿されました。)
JavaScriptで指要素を書き換える方法としてinnerHTMLがあります。
innerHTMLとは指定した要素の子要素の書き換えや取得を行うプロパティとなります。
そのため、画面上の要素を変更したり、要素の値を取得したい場合に使用することができます。
また、HTMLタグとして認識するため、値だけでなくHTML要素として書き換えることもできます。
しかし、innerHTMLはリスクもありますので注意して使用するようにしましょう。
今回はJavaScriptのinnerHTMLで要素の値を書き換える方法について紹介していきます。
・指定した要素の子要素を取得したい場合
innerHTML()とは
innerHTML()と指定した要素の子ノードを操作するプロパティになります。
そのため、指定した子ノードを書き換えたり、取得したりすることができます。
innerHTMLの書き方
innerHTMLの書き方は下記のようになります。
1 | セレクタ.innerHTML = 変更する値 |
セレクタの後ろにinnerHTMLと入力し、変更する値をイコールでつなげることで、要素の書き換えが可能になります。
また、下記のように記載することもできます。
1 | 変数名 = セレクタ.innerHTML |
セレクタの後ろにinnerHTMLと入力し、変更名とイコールでつなげることで、指定したセレクタの値を取得することができます。
innerHTMLの対象範囲
innerHTMLの対象範囲は指定したHTML要素の子要素の開始タグから終了タグとなります。
innerHTMLで要素の内容を書き換えるサンプルコード
innerHTMLで要素の内容を書き換えるサンプルコードをご紹介します。
ここでは、下記の3つのパターンでinnerHTMLを使用します。
- 要素の値を書き換える場合
- 要素のHTMLタグごと書き換える場合
- 要素の値を削除する場合
要素の値を書き換える場合
innerHTMLで要素の値を書き換えるには変更したい値を文字列で指定します。
● index.html
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | <!DOCTYPE html> <html lang="ja"> <head> <meta charset="UTF-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <script src = "main.js"></script> <title>innerHTML使用</title> </head> <body> <h3>innerHTMLで要素を書き換え</h3> <div class= "divArea"> <p class ="pArea">この要素を書き換える</p> </div> </body> </html> |
● main.js
1 2 3 4 | window.addEventListener('load', function() { let divArea = document.querySelector(".divArea") divArea.innerHTML = "別の要素に書き換えました。" }) |
実行結果
innerHTMLによって要素の値を書き換えています。
そのため、「この要素を書き換える」から「別の要素に書き換えました。」に変更されて表示されています。
また処理後のソースを確認すると、値が変更されていることがわかります。
処理後のソース
要素の別の要素に書き換える場合
innerHTMLで要素の別の要素に書き換えるにはHTMLタグが入った値を文字列で指定します。
innerHTMLはHTMLタグを認識するため、HTML要素を文字列で指定することで別の要素に書き換えが可能になります。
● index.html
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 | <!DOCTYPE html> <html lang="ja"> <head> <meta charset="UTF-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <script src = "main.js"></script> <title>innerHTML使用</title> </head> <body> <h3>innerHTMLで要素を書き換え</h3> <div class= "divArea"> <p class ="pArea">この要素を書き換える</p> </div> </body> <style> .redBold { color: red; font-weight: bold; } </style> </html> |
● main.js
1 2 3 4 | window.addEventListener('load', function() { let divArea = document.querySelector(".divArea") divArea.innerHTML = '<span class= "redBold">別の要素に書き換えました。</span>' }) |
実行結果
innerHTMLによって要素の別の要素に書き換えています。
今回は「redBold」クラスを付与した「spanタグ」から書き換えたため、「別の要素に書き換えました。」が赤色の太字で表示されています。
また処理後のソースを確認すると、要素の中ににpanタグの要素が追加されていることがわかります。
処理後のソース
要素を削除する場合
innerHTMLで要素を削除するには、innerHTMLに「“”(空文字)」を指定します。
指定した要素の子要素を空文字に書き換えるため、要素の削除が可能になります。
● index.html
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | <!DOCTYPE html> <html lang="ja"> <head> <meta charset="UTF-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <script src = "main.js"></script> <title>innerHTML使用</title> </head> <body> <h3>innerHTMLで要素を書き換え</h3> <div class= "divArea"> <p class ="pArea">この要素を書き換える</p> </div> </body> </html> |
● main.js
1 2 3 4 | window.addEventListener('load', function() { let divArea = document.querySelector(".divArea") divArea.innerHTML = '' }) |
実行結果
innerHTMLによって指定した要素を削除しています。
そのため、「この要素を書き換える」という要素が表示されていません。
また、処理後のソースを確認すると、コードが削除されていることがわかります。
処理後のソース
innerHTMLで要素の値を取得する場合
innerHTMLは要素の値を書き換えるだけでなく、要素の値を取得することもできます。
● index.html
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | <!DOCTYPE html> <html lang="ja"> <head> <meta charset="UTF-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <script src = "main.js"></script> <title>innerHTML使用</title> </head> <body> <h3>innerHTMLで要素を書き換え</h3> <div class= "divArea"> <p class ="pArea">この要素を書き換える</p> </div> </body> </html> |
● main.js
1 2 3 4 5 | window.addEventListener('load', function() { let divArea = document.querySelector(".divArea") let html = divArea.innerHTML console.log(html) }) |
実行結果
そのため、「<p class =”pArea”>この要素を書き換える</p>」が表示されています。
innerHTMLとinnerTextの違い
JavaScriptにはinnerHTMLとよく似た、innerTextが存在します。
innerTextとは指定した要素の値を書き換えたり、取得したりするプロパティであり、innerHTMLと類似したプロパティとなります。
しかし、この2つの違いは「書き換える時にHTMLタグを認識するかしないか」が大きな違いとなります。
例えば下記のコードを見て下さい。
● index.html
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | <!DOCTYPE html> <html lang="ja"> <head> <meta charset="UTF-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>innerHTML使用</title> </head> <body> <h3>innerHTMLとinnerTextの違い</h3> <div class= "divArea1"> <p class ="pArea1">innerHTML</p> </div> <div class= "divArea2"> <p class ="pArea2">innerText</p> </div> </body> </html> |
● main.js
1 2 3 4 5 6 7 8 | window.addEventListener("load", function() { let divArea1 = document.querySelector(".divArea1") let changeHtml1 = '<p class= "inner">innerHTMLで要素を変更します。</p>' divArea1.innerHTML = changeHtml1 let divArea2 = document.querySelector(".divArea2") let changeHtml2 = '<p class= "inner">innerTextで要素を変更します。</p>' divArea2.innerText = changeHtml2 }) |
実行結果
innerHTMLはPタグの「innerHTMLで要素を変更します。」に書き換えていますが、innerTextは「<p>innerTextで要素を変更します。</p>」に書き換えています。
そのため、タグを認識して書き換えるか書き換えないというのがinnerHTMLとinnerTextの大きな違いです。
つまり、要素の内部のHTMLを変更する場合はinnerHTMLを使用し、要素の内部のテキストを変更する場合はinnerTextを使用するようにしましょう。
innerHTMLを使用する際の注意点
指定した要素の値を書き換えることができるinnerHTMLですが、注意しておかなければならないことがあります
そのため、ここではinnerHTMLを使用する際の注意点ついてご紹介します。
意図しない挙動を引き起こす可能性がある
innerHTMLは、文字列をそのままHTMLとして解釈してしまうため、不正なHTMLタグやスクリプトが含まれている場合、意図しない挙動を引き起こす可能性があります。
例えば下記のように、innerHTMLでframeの要素を追加したとします。
● index.html
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <script src = "main.js"></script> <title>innerHTML使用</title> </head> <body> <h3>innerHTML使用</h3> <div class= "divArea"> <p class ="pArea">innerHTML</p> </div> </body> </html> |
● main.js
1 2 3 4 5 6 7 8 9 | window.addEventListener("load", function() { let divArea = document.querySelector(".divArea") let changeHtml = '<iframe src="index.html" onload="loadEvent()"></iframe>'; divArea.innerHTML = changeHtml }) function loadEvent() { alert("Error") } |
実行結果
innerHTMLによって「iframeタグ」が埋め込まれ、onload属性内にあるloadEvent関数が発生し、アラートが表示されています。
つまり、文字列として追加したはずの値がHTML要素と認識され、設定していた関数が実行されてしまったということです
このような発生を防ぐためにinnerHTMLに挿入する文字列は、HTMLエンティティやサニタイズ処理などを行って、HTMLタグやスクリプトを無効化する必要があります。
このようにWebサイトの脆弱性を悪用して罠を仕掛け、悪意のあるスクリプトが仕込まれることがあります。
これをクロスサイトスクリプティング(XSS)といいます。
使いすぎるとパフォーマンスが低下する可能性がある
innerHTMLは、DOMを書き換えるため、使いすぎるとパフォーマンスが低下する可能性があります。
例えば、for文を使用してinnerHTMLとinnerTextをそれぞれ1000回繰り返し、かかった時間を計測します。
● index.html
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 | <!DOCTYPE html> <html lang="ja"> <head> <meta charset="UTF-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <script src = "main.js"></script> <title>innerHTML使用</title> </head> <body> <h3>innerHTMLとinnerTextの時間計測</h3> <div class= "divArea1"> <p class ="pArea1"></p> </div> <div class= "divArea2"> <p class ="pArea2"></p> </div> </body> </html> |
● main.js
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | console.log("● innerHTML"); let startTime1 = new Date(); let divArea1 = document.querySelector(".divArea1") for(i = 0; i < 1000; i++) { let changeHtml1 = '<p>innerHTMLで要素を変更します。</p>' divArea1.innerHTML = changeHtml1 } let endTime1 = new Date(); let diffTime1 = endTime1 - startTime1; // console.log("処理にかかった時間は" + diffTime1 + "ミリ秒です。"); console.log("● innerText"); let startTime2 = new Date(); let divArea2 = document.querySelector(".divArea2") for(j = 0; j < 1000; j++) { let changeHtml2 = 'innerTextで要素を変更します。' divArea2.innerText = changeHtml2 } let endTime2 = new Date(); let diffTime2 = endTime2 - startTime2; console.log("処理にかかった時間は" + diffTime2 + "ミリ秒です。"); |
実行結果
実行結果(ログ)
結果からして何も変わらないように感じるかと思います。
しかし、ログを見てみると、「2ミリ秒」かかっているinnerTextに比べて、innerHTMLは「13ミリ秒」かかっており、innerHTMLの方が負荷が大きいことがわかります。
そのため、数少ない要素を書き換えるのには問題はありませんが、数が多い場合はinnerHTMLの使用を控えるようにしましょう。
innerHTMLを使用した実際のケース
innerHTMLを使用した実際のケースについてご紹介します。
ここでは、innerHTMLを使用して追加、修正機能が付いたTodoリストを作成します。
● index.html
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 | <!DOCTYPE html> <html lang="ja"> <head> <meta charset="UTF-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <script src = "main.js"></script> <title>innerHTML使用</title> </head> <body> <h3>innerHTMLでTodoリスト作成</h3> <div class= "appArea"> <input id="tskInp" type="text" placeholder="タスクを入力してください"> <button id="addButton">追加</button> <button id="chngButton">変更</button> <div id="taskList"></div> </div> </body> </html> |
● main.js
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 | window.addEventListener('load', function() { let tskInp = document.querySelector("#tskInp") let tsklist = document.querySelector("#taskList") let addBtn = document.querySelector("#addButton") let cnt = 1 addBtn.addEventListener('click', createTask) chngButton.addEventListener('click', changeTask) function createTask() { let tskVal = tskInp.value let html = document.createElement("p") html.textContent = tskVal html.className = "task" + cnt let rdo = document.createElement("input") rdo.type = "radio" rdo.name = "task" rdo.value = html.className html.appendChild(rdo) tsklist.appendChild(html) cnt = cnt + 1 } function changeTask() { let tskRadio = document.getElementsByName('task') let checkValue = "" for (let i = 0; i < tskRadio.length; i++){ if (tskRadio.item(i).checked){ checkValue = tskRadio.item(i).value; } } if(checkValue == "") { alert("ボタンを選択してください。") return false } className = "."+ checkValue console.log(className) changedVal = document.querySelector(className) chngRdo = `<input type="radio" name="task" value="${checkValue}">` if(tskInp.value == "") { alert("テキストを入力してください。") return false } changedVal.innerHTML = tskInp.value + chngRdo } }) |
実行結果
innerHTML()によってTodoリストが作成されています。
今回は修正ボタンを押した際にinnerHTMLによって、入力した値を反映するようにしています。
自分自身と中身のHTML要素を書き換える場合
自分自身と中身のHTML要素を書き換える場合は、outerHTMLを使用します。
outerHTMLは、指定したHTML要素ごと書き換えたり、取得したりするプロパティになります。
そのため、今回紹介しているinnerHTMLの範囲が広がったプロパティとなります。
● index.html
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 | <!DOCTYPE html> <html lang="ja"> <head> <meta charset="UTF-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <script src = "main.js"></script> <title>innerHTML使用</title> </head> <body> <h3>outerHTMLで自分自身の要素を書き換え</h3> <div class= "divArea"> <p class ="pArea">この要素を書き換える</p> </div> </body> <style> .divAreaCng { border: 2px solid black; font-size: 20px; color: blue; } </style> </html> |
● main.js
1 2 3 4 5 | window.addEventListener("load", function() { let divArea = document.querySelector(".divArea") let changeHtml = '<div class= "divAreaCng"><p class ="pAreaCng">この要素を書き換えました。</p></div>' divArea.outerHTML = changeHtml }) |
実行結果
outerHTMLによって指定したタグの要素が作成されています。
そのため、「この要素を書き換えました。」という文字列が表示されています。
また、処理後のソースコードを見ると、指定した要素自身から書き換わっていることがわかります。
処理後のソース
まとめ
⚫︎ innerHTMLとは指定した要素の子要素を書き換えたり、取得したりするプロパティである
⚫︎ innerHTMLで要素の値を書き換えるには値を文字列で指定する
⚫︎ innerHTMLで要素を別の要素に書き換えるにはHTMLタグごと文字列で指定する
⚫︎ innerHTMLで要素の値を削除するには空文字を指定する
⚫︎ 変数に対してinnerHTMLを使用すると、要素の値を取得できる
⚫︎ innerHTMLとinnerTextとの違いは「書き換える時にHTMLタグを認識するかしないか」である
(innerTextだとすべて文字列として書き換えるが、innerHTMLはHTMLタグはタグと認識して書き換える)
⚫︎ innerHTMLは下記の点に注意して使用する
・予想していない処理が行われる可能性がある
・使いすぎるとパフォーマンスが低下する可能性がある
⚫︎ 自分自身と中身のHTML要素を書き換える場合はouterHTMLを使用する