Does anyone have a good reason to use one over the other? As far as I can tell, create/append node simply prevents you from creating invalid code, while innerHTML allows you to inject multiple nodes at once.
Given that I need to insert several tags, it seems to make sense to use innerHTML. Does anyone have a different take?
This is always a contentious argument, partially because the origin of innerHTML
being somewhat dubious from a standards perspective. I think the QuirksMode article is still relevant, but I'd love to see it updated. Perhaps contact ppk about updating them, though I'm sure he's busy. We could all benefit from performance testing the assumptions we make in web development. In the end claims require hard data to prove, otherwise it's really just talk.
Anyway, I did some searching and found some interesting articles relevant to this discussion. I don't remember hearing of DocumentFragments before, they're real interesting.
Given that I need to insert several tags, it seems to make sense to use innerHTML.
Only ‘several’? Then speed is not an issue. It's when you're creating a hundred you have to think about what you're doing. It's not really the creating that's the problem, it's the child node list manipulation that gets slower and slower as you add each extra element.
As for appending, you don't really have any choice. You can't set the innerHTML without losing the existing content, so unless you're happy with serialising and re-parsing that (which wipes out any non-serialisable data like form contents, JavaScript properties/references and event handlers) you end up setting the innerHTML of another element and moving each child over one by one. This is what many frameworks do and it typically ends up even slower than manual create-and-appendChild.
Depending on your situation (specifically: how many child nodes are already in the target element, and how many are you going to add?) it can be faster to break down the operation into smaller manipulations on a DocumentFragment, whose children can be appended to an element's children all in one go instead of one-by-one. This is much faster. Unfortunately, it is not possible to set innerHTML
on a DocumentFragment.
There may also be faster hacks using Range objects to move a load of HTML at once, but unfortunately Ranges are highly cross-browser variable. It seems to me, though, that someone ought to be able to build a fast append-html out of IE's range.pasteHTML and W3's range.extractContents. Anyone up for it?
As far as I can tell, create/append node simply prevents you from creating invalid code
Potentially invalid markup doesn't just mean your application breaks in some browsers. When you're blindly splicing together HTML without escaping like an idiot:
element.innerHTML= '<a href="'+url+'">'+title+'</a>';
then you have a client-side cross-site-scripting security hole that is just as bad as a server-side one.
You can, of course, compromise, by creating the elements and setting their contents in separate steps. For example:
element.innerHTML= '<table>'+'<tr><td>X</td><td><a href="#">go</a></td></tr>'.repeated(urls.length)+'</table>';
for (var i= 0; i<urls.length; i++) {
var row= element.firstChild.rows[i];
row.cells[0].firstChild.data= urls[i];
row.cells[1].firstChild.href= urls[i];
}
(string.repeated is not standard JavaScript, but its use here is obvious.)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With