Building with jQuery, IE and invalid markup

Ran into an interesting problem when using jQuery to generate DOM from markup: make sure your markup is valid, otherwise jQuery's html function will fail silently in Internet Explorer.

A quick and simple illustration with some invalid markup:

$('#content').html('<div>content</div></div>');

Firefox ignores the second div, but IE does not, and causes it to fail. You will instead find that the innerHTML of your #content element is empty.

This won't happen every time, and depends on exactly how your markup is broken; for example, <div><div>content</div> is also wrong, but will not cause this problem.

As any js developer will testify, these are the most fun kind of problems, especially when the line in question is part of a far larger library, buried in a series of asynchronous anonymous functions, and surrounded by various things that are far more likely to be the cause, such as non-json cross-domain POSTs and GETs, for example. Needless to say, the problem first appeared to be completely unrelated, and I wasted a fair bit of time on this one.

The issue actually seems to be in jQuery.clear(), so it affects html(), jQuery(html), append(), prepend(), after(), before() etc - in fact, any jQuery function that is supposed to parse raw html and add it to the DOM. Functions that set or replace content will set it to nothing; ones that append or prepend content will leave existing content unaffected.

There are several obvious ways to test for this failure, but the easiest seems to be to check whether the html() is null:

var $newContent = $('<div>content</div></div>');
if ($newContent.html() == null) {
    // The content was invalid in IE, raise an error
    return;
}
$('#content').empty().append($newContent);

Simple solution, simple problem, bloody annoying.

Leave a comment