Interesting side affect of creating DOM objects using innerHTML

It’s ER night again tonight so I’m going to update with a totally dorky technical web thing I did today that I thought was interesting. :)

I found a strange IE behaviour today in a sample I was looking at. The problem was with a javascript object that had a reference to a DOM object. After the code added a new node to the DOM object’s parent of the DOM object using the parent node’s innerHTML property, the javascript object’s reference to the DOM object was broken.

I had a webpage that looked something like this with an element (outerDiv) which I wanted to use innerHTML to add some more children too. It had a couple of child nodes already:

  1. <div id="outerDiv">
  2.  <div id="innerDiv">
  3.   <p>Hello world</p>
  4.  </div>
  5. </div>

I also had a javascript object that had a reference to one of the children of outerDiv (innerDiv):

  1. var myObject = {};
  2. myObject.Element = document.getElementById("innerDiv");

Then I appended another element at the end of the outerDiv using the outerDiv’s innerHTML property:

  1. document.getElementById("outerDiv").innerHTML += "<div id='generatedDiv'></div>";

After doing this the myObject’s Element property is still pointing to a HTML element that at first glance seems to be the original one. However if you have a look at some of its properties (I noticed the childNodes collections) you’ll notice that they’re empty and anything you set on Element won’t change any the properties on the real innerDiv element.

I think what’s actually happening is that IE is actually creating totally new elements inside outerDiv whenever you change the innerHTML and it doesn’t automatically update the references from any javascript objects that reference them.

I’m not 100% surprised it didn’t work. It seems like something that’s likely to be fragile. It might not even be a bug. I guess this sort of thing was why innerHTML wasn’t in the original DOM standard. Interestingly enough this doesn’t affect Firefox. When I ran my sample in Firefox it worked fine.

The workaround’s simple. You just have to create the elements using document.createElement() instead and then manually append them to outerDiv’s child collection:

  1. var div = document.createElement("div"); = "generatedDiv";
  2. document.getElementById("outerDiv").appendChild(div);

See it in action on my sample page.

Posted on 15 Mar 07 by Helen Emerson (last updated on 15 Mar 07).
Filed under Browser quirks