28
votes

See the solution at the bottom of the question.

IE 8 (and lower) does not work good with unknown elements (ie. HTML5 elements), one cannot style them , or access most of their props. Their are numerous work arounds for this for example: http://remysharp.com/2009/01/07/html5-enabling-script/

The problem is that this works great for static HTML that was available on page load, but when one creates HTML5 elements afterward (for example AJAX call containing them, or simply creating with JS), it will mark these newly added elements them as HTMLUnknownElement as supposed to HTMLGenericElement (in IE debugger).

Does anybody know a work around for that, so that newly added elements will be recognized/enabled by IE 8?

Here is a test page:

<html><head><title>TIME TEST</title>
    <!--[if IE]>
    <script src="http://html5shiv.googlecode.com/svn/trunk/html5.js"></script>
<![endif]-->
    <script src="http://ajax.googleapis.com/ajax/libs/jquery/1.4.2/jquery.min.js" type="text/javascript"></script>
</head>

<body>
    <time>some time</time>
    <hr>
    <script type="text/javascript">
        $("time").text("WORKS GREAT");
        $("body").append("<time>NEW ELEMENT</time>"); //simulates AJAX callback insertion
        $("time").text("UPDATE");
    </script>
</body>
</html>

In IE you will see the: UPDATE , and NEW ELEMENT. In any other modern browser you will see UPDATE, and UPDATE

5
Read my blog about how to use innerShiv and jQuery for ajaxing in HTML 5 content. tomcoote.co.uk/javascript/ajax-html5-in-ieuser645590

5 Answers

25
votes

for all html5 issues in IE7 i use html5shiv and to accommodate the html5 elements coming back in ajax calls i use innershiv.

these two small plugins worked for me like a charm so far.

-- Praveen Gunasekara

4
votes

jQuery has some dark, magical ways of creating elements. Using document.createElement instead should make all the difference:

var time = document.createElement("time");
time.innerHTML = "WORKS GREAT";
document.appendChild(time);

I do not believe you can use the .append() syntax (like .innerHTML += "") with HTML5 and IE. The problem isn't IE's ability to use or display the HTML5 elements, it's its ability to parse them. Any time you programmatically instantiate an HTML5 element, you must do it with document.createElement.

2
votes

I too ran into trouble when fetching a bunch of HTML containing HTML5 elements from the server using AJAX. html5shiv wasn't able to save my day. My project template is based on the html5boilerplate and uses Modernizr to fix HTML5 tag behavior in IE < 9. After reading this thread I got a hunch and managed to get my code working.

The problematic code injecting the freshly squeezed HTML into the DOM was:

var wrapper = $('<div />')
    .addClass('wrapper')
    .html(data.html)
    .appendTo(wrapper);

Basically what happens here is:

  1. create a new element
  2. the innerHTML of the new element is updated
  3. the new element with its innerHTML is appended to an existing element in the DOM

Changing it to the following fixes my problem:

var wrapper = $('<div />')
    .addClass('wrapper')
    .appendTo(el);
wrapper.html(data.html);

What happens now is:

  1. create a new element
  2. the empty new element is appended to an existing element in the DOM
  3. the innerHTML of the newly appended element is updated

Now even IE7 has no choice but to display asynchronously loaded HTML5 elements like I want it to :)

Thanks Julio, will keep your plugin handy in case I need it in the future. But for now I am happy not to add the overhead of the extra DOM manipulations.

Maybe this workaround works for some other people too.

2
votes

note that innershiv functionality is built into jquery as of 1.7 http://blog.jquery.com/2011/11/03/jquery-1-7-released/

0
votes

Just leaving this to contribute to the discussion.

The script provided that @Gidon seems not working in IE8 (tested on two different machines). I had to remake the jQuery plugin in another way, see below:

/**
 * Enable HTML5 Elements on the fly. IE needs to create html5 elements every time.
 * @author Gidon
 * @author Julio Vedovatto <[email protected]>
 * @see http://stackoverflow.com/questions/2363040/how-to-enable-html5-elements-in-ie-that-were-inserted-by-ajax-call
 */
(function ($) {
    jQuery.fn.html5Enabler = function () {
        var element = this;

        if (!$.browser.msie)
            return element;

            $.each(
                ['abbr','article','aside','audio','canvas','details','figcaption','figure','footer','header','hgroup','mark','menu','meter','nav','output','progress','section','summary','time','video'],
                function() {
                    if ($(element).find(this).size() > 0) {
                        $(element).find(this).each(function(k,child){
                            var el = $(document.createElement(child.tagName));

                            for (var i = 0; i < child.attributes.length; i++)
                                el.attr(child.attributes[i].nodeName, child.attributes[i].nodeValue);

                            el.html(child.innerHTML);

                            $(child).replaceWith(el);
                        });
                    }
                }
            );
    };
})(jQuery);