Search code examples
javascripthtmlinnerhtmldom-events

Is it possible to append to innerHTML without destroying descendants' event listeners?


In the following example code, I attach an onclick event handler to the span containing the text "foo". The handler is an anonymous function that pops up an alert().

However, if I assign to the parent node's innerHTML, this onclick event handler gets destroyed - clicking "foo" fails to pop up the alert box.

Is this fixable?

<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>

Solution

  • Unfortunately, assignment to innerHTML causes the destruction of all child elements, even if you're trying to append. If you want to preserve child nodes (and their event handlers), you'll need to use DOM functions:

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

    Edit: Bob's solution, from the comments. Post your answer, Bob! Get credit for it. :-)

    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);
        }
    }