Skip to content

Instantly share code, notes, and snippets.

@jakearchibald jakearchibald/gist:4489851
Last active Dec 10, 2015

Embed
What would you like to do?
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

This comment has been minimized.

Copy link

commented Jan 9, 2013

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

Okay, sure. Burn me now.

@jakearchibald

This comment has been minimized.

Copy link
Owner Author

commented Jan 9, 2013

HERESY

@joemarini

This comment has been minimized.

Copy link

commented Jan 9, 2013

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

This comment has been minimized.

Copy link

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

This comment has been minimized.

Copy link

commented Jan 9, 2013

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

This comment has been minimized.

Copy link
Owner Author

commented Jan 9, 2013

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
You can’t perform that action at this time.