Skip to content

Instantly share code, notes, and snippets.

@jakearchibald
Last active December 10, 2015 20:38
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save jakearchibald/4489851 to your computer and use it in GitHub Desktop.
Save jakearchibald/4489851 to your computer and use it in GitHub Desktop.
Setting innerHTML and IE

What do you think this will output?

var div = document.createElement('div');
div.innerHTML = '<span>Hello world!</span>';
var span = div.firstChild;
div.innerHTML = '<span>Uh oh!</span>';
console.log(span.innerHTML);

Go on, have a guess.

Ok, here's what happens:

According to the spec, setting innerHTML removes all children from the node (as if you called removeChild on each). The span we pulled out is detached, but otherwise unmodified, so "Hello world!" is logged. This is what Chrome, Firefox & Opera do.

IE has done this differently for as long as I can remember (and still does in IE10). Setting innerHTML removes all descendants from their parents, so we still have a reference to a span, but it's empty, so "" is logged.

@remy
Copy link

remy commented Jan 9, 2013

That kinda...sorta...makes sense (what IE is doing).

Okay, sure. Burn me now.

@jakearchibald
Copy link
Author

HERESY

@joemarini
Copy link

No, that doesn't make sense at all. According to the spec, removeChild() returns a reference to the removed child. You can then reuse it elsewhere in the document if you want to. Removing a child shouldn't alter its contents.

@NickFitz
Copy link

NickFitz commented Jan 9, 2013

Given that innerHTML started life as an IE-only feature back in IE4, it could be argued that whatever IE does is, by definition, the correct behaviour, and that therefore the spec and the other browsers are wrong.

@rkrupinski
Copy link

Does this IE behaviour still make sense?

var div = document.createElement('div');
div.innerHTML = '<span class="foo">Hello world!</span>';
var span = div.firstChild;
div.innerHTML = '<span>Uh oh!</span>';
console.log(span.className); // foo
console.log(span.innerHTML); //

@jakearchibald
Copy link
Author

NickFitz: Fair point. XMLHttpRequest went through the same thing, MS invented it, other browsers implemented a slightly more sane version that went into the spec.

rkrupinski: Basically, most browsers are doing this

while (element.firstChild) {
  element.removeChild(element.firstChild);
}

whereas IE is doing:

var elements = element.getElementsByTagName('*');

while (elements[0]) {
  elements[0].parentNode.removeChild(elements[0]);
}

…before parsing the new markup string.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment