Im having a really weird IE problem that I can’t figure out what the root cause is. I’m hoping to get an explanation as to what internally is going wrong. I can append a dynamically created element to another once, but any subsequent attempts to append the node removes any children appended to it.
I have a function create a wrapper div, and then appends a child ‘p’ with some text attached to it. Function essentially reads like this:
function buildElement(text){
var node,p,doc = document;
node = doc.createElement('div');
node.setAttribute('class','node-wrapper');
p = doc.createElement('p');
p.appendChild(doc.createTextNode(text));
node.appendChild(p);
return node;
}
It’s pretty straight forward. This builds an element that contains the text that you pass into it. Heres a scaled down version of what I’m trying to do, and comments to describe what’s happening in IE:
// create a parent wrapper element
var wrapper = document.createElement('div');
wrapper.setAttribute('class','parent-wrapper');
var childNode = buildElement('This is a sample');
// This will append a child node with all of its children,
// everything works as expected - ex:
// <div class="parent-wrapper">
// <div class="node-wrapper">
// <p>This is a sample</p>
// </div>
// </div>
wrapper.appendChild(childNode);
// empty the parent wrapper
wrapper.innerHTML = '';
// re-append the childNode element to the parent wrapper
// in IE, this step will fill the parent node with just the node-wrapper element
// with the removed child node(s) - ex:
// <div class="parent-wrapper">
// <div class="node-wrapper" />
// </div>
wrapper.appendChild(childNode);
What you’ll see if you run this, is that the first wrapper.appendChild(childNode) works great and as expected. But the second attempt to append the child node will result in the childNode’s children being removed from the childNode. (ex: the ‘p’ is gone.);
You can see a working example of this here:
http://jsfiddle.net/jiggliemon/52ZPR/
What’s weird is that you can avoid the child-node removal by not appending the childNode, but appending a Clone of the child node wrapper.appendChild(childNode.cloneNode(true)).
You can see a working example of this here:
http://jsfiddle.net/jiggliemon/52ZPR/3/
Here is a more elaborate example:
http://jsfiddle.net/jiggliemon/bcSpQ/
wrapper.innerHTML = ''seems to damage your inner nodes. Don’t use it. The correct technique is
This should fix your bug.
However other then saying
innerHTMLis bad! I can’t explain your bug.The HTML5 specification says :
So it really should not be damaging
childNodeAs a side-note:
p.textContent = text;is the “same” as
p.appendChild(doc.createTextNode(text));As a further aside the idea that
x.innerHTML = ''is a fast way to empty x is a lie.
Benchmark
Please use a while loop over the firstChild or set
.textContent = ''