Thursday, August 26th, 2010

innerShiv: Make innerHTML + HTML5 Work in IE

Category: IE, Library

>(Various Shivs)

Via JD Bartlett comes HTML5 innerShiv for IE. Before innerShiv, the following would not work in IE:

  1. var s = document.createElement('div');
  2. s.innerHTML = "<section>Hi!</section>";
  3. document.body.appendChild(s);

For example, let’s imagine we have some CSS that defines the following for the HTML5 elements footer, header, and section:

  1. footer, header, section {
  2.   border:1px solid #ccc;
  3.   display:block;
  4.   padding:10px;
  5. }

Unfortunately, even if you are using one of the tricks to force IE to deal with HTML5 elements shivs don’t work when dealing with innerHTML before an element is appended to the DOM:

However, the shiv doesn’t work in Internet Explorer when an element’s content is added with innerHTML before being appended to the document. That’s a common use case, and noticeable in libraries like jQuery when you try to append or load (etc.) HTML5 content

Some example bad JQuery code that runs into this problem:

javascript
< view plain text >
  1. $('#example-1').append("<section><header><h3>Example 1:\
  2.   a broken section</h3></header><p>This section element should\
  3.   have a black border like the others. It doesn't in Internet\
  4.   Explorer. :(</p></section>");

JD’s library is the solution to this problem:

innerShiv is a function which takes your HTML string, adds it to a hidden document-appended element in IE, and returns an IE-safe document fragment or collection

Now you can do the following to have things work:

javascript
< view plain text >
  1. $('#example-2').append(innerShiv("<section><header><h3>\
  2.   Example 2: a successfully styled section</h3></header>\
  3.   <p>This section element should have a gray border like the\
  4.   others. And it does! Even in Internet Explorer! Yay!.</p>\
  5.   </section>"));

Note that you don’t have to use JQuery to use innerShiv.

Related Content:

Posted by Brad Neuberg at 5:00 am
5 Comments

++---
2.2 rating from 5 votes

5 Comments »

Comments feed TrackBack URI

I don’t see HTML5 structural elements being useful until they are supported in all browsers. The pain/payoff ratio is just not worth it.

Comment by khs4473 — August 26, 2010

Note that you don’t have to use innerHTML ever.
.
Did people forget about document.createElement or is it that these days only designers with no programming knowledge do javascript and implement aberrations like that code snippet?
How is that piece using innerHTML ever supposed to scale? just add more crude HTML on that abomination of a string?

Comment by gonchuki — August 26, 2010

gonchuki,

createElement can be quite slow, and requires more code. That isn’t to say that innerHTML is “superior”, but that it has its uses and to dismiss it entirely is to be even more conservative than the HTML5 DOM. The concern of having arbitrary HTML in the behavior layer is real, but can be alleviated by getting HTML templates from another resource; the actual code executed may still be the same, but it allows better maintenance.

Comment by eyelidlessness — August 26, 2010

@eyelidlessness,
so better maintenance means editing a huge string that lacks proper indenting and whitespaces in which you can even throw tag soup and no validator will be able to help you debug that malformed code?
.
Don’t fall in the cargo cult that document.createElement is slow. It depends on browser implementation and how tuned is your code. I created a test in jsperf and I’m not getting the innerHTML version any faster than the DOM one. In fact, DOM runs twice as fast as innerHTML in Chome, Firefox and even IE. Even better, the DOM version does proper cleanup and can hold a reference to the inserted node without any extra effort (you would need at the very least a document.getElementsByTagName to fetch your innerHTML div)
.
test it yourself: http://jsperf.com/dom-vs-innerhtml/2

Comment by gonchuki — August 26, 2010

Using innerHTML is wrong as it’s horribly unreliable in applications. Also I’m getting fairly sick of seeing jQuery so consistently as it’s also not reliable in my experience. Stick to the DOM and object detection.

Comment by jabcreations — October 8, 2010

Leave a comment

You must be logged in to post a comment.