141

次のサンプルコードでは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>
4

13 に答える 13

149

残念ながら、への代入はinnerHTML、たとえ追加しようとしても、すべての子要素の破棄を引き起こします。子ノード (およびそのイベント ハンドラー) を保持する場合は、 DOM 関数を使用する必要があります。

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

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

編集:コメントからのボブの解決策。答えを投稿してください、ボブ! それの信用を得てください。:-)

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);
    }
}
于 2009-02-27T17:47:07.483 に答える
3

文字列として挿入するマークアップを作成しました。これは、派手な dom で作業するよりもコードが少なく読みやすいためです。

次に、一時要素の innerHTML を作成して、その要素の唯一の子を取得して本体にアタッチできるようにしました。

var html = '<div>';
html += 'Hello div!';
html += '</div>';

var tempElement = document.createElement('div');
tempElement.innerHTML = html;
document.getElementsByTagName('body')[0].appendChild(tempElement.firstChild);
于 2012-07-04T08:08:16.507 に答える
3

現在は 2012 年ですが、jQuery には、現在のコンテンツに影響を与えずにコンテンツを追加する、まさにこれを行う追加機能と先頭追加機能があります。非常に便利。

于 2012-01-20T18:06:15.423 に答える
0

イベントハンドラーを失うことは、IMO、Javascript が DOM を処理する方法のバグです。この動作を回避するには、次を追加できます。

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

  mydiv = document.getElementById("mydiv");
  clickHandler = mydiv.onclick;  // add
  mydiv.innerHTML += "bar";
  mydiv.onclick = clickHandler;  // add
}
于 2009-02-27T17:48:44.593 に答える
-7

私は怠惰なプログラマーです。余分な入力のように見えるので、DOM は使用しません。私にとっては、コードが少ないほど良いです。「foo」を置き換えずに「bar」を追加する方法は次のとおりです。

function start(){
var innermyspan = document.getElementById("myspan").innerHTML;
document.getElementById("myspan").innerHTML=innermyspan+"bar";
}
于 2010-07-09T14:46:13.687 に答える