1. ホーム
  2. javascript

[解決済み] 子孫のイベントリスナーを破壊せずにinnerHTMLに追記することは可能ですか?

2022-05-27 01:55:04

質問

以下のコード例では onclick イベント ハンドラをテキスト "foo" を含むスパンにアタッチしています。このハンドラは無名関数で、この関数によって alert() .

しかし、親ノードの innerHTML に割り当てると、この onclick イベントハンドラは破壊されます - "foo" をクリックしても警告ボックスをポップアップすることができません。

これは修正可能ですか?

<html>
 <head>
 <script type="text/javascript">

  function start () {
    myspan = document.getElementById("myspan");
    myspan.onclick = function() { alert ("hi"); };

    mydiv = document.getElementById("mydiv");
    mydiv.innerHTML += "bar";
  }

 </script>
 </head>

 <body onload="start()">
   <div id="mydiv" style="border: solid red 2px">
     <span id="myspan">foo</span>
   </div>
 </body>

</html>

どのように解決するのですか?

残念ながら innerHTML に代入すると、たとえ追加しようとしている場合でも、すべての子要素が破壊されます。 子ノード(とそのイベントハンドラ)を保持したい場合には DOM 関数 :

function start() {
    var myspan = document.getElementById("myspan");
    myspan.onclick = function() { alert ("hi"); };

    var mydiv = document.getElementById("mydiv");
    mydiv.appendChild(document.createTextNode("bar"));
}

編集します。 ボブさんの解答、コメントより。 答えを投稿してください、Bob! 自分の手柄にしちゃいましょう :-)

function start() {
    var myspan = document.getElementById("myspan");
    myspan.onclick = function() { alert ("hi"); };

    var mydiv = document.getElementById("mydiv");
    var newcontent = document.createElement('div');
    newcontent.innerHTML = "bar";

    while (newcontent.firstChild) {
        mydiv.appendChild(newcontent.firstChild);
    }
}