Internet Explorer and innerHTML in PRE elements
080924
While I was working on modifying SHJS (a JavaScript syntax highlighter), I came across a very frustrating (and initially extremely puzzling) IE bug. Well, it might not be a bug, but it's a very strange and illogical behaviour. In short: IE performs text normalization when setting innerHTML. Sebastian Redl explains it in The Internet Explorer innerHTML Quirk.
Here's an example: imagine that we have a string that includes line breaks, tabs and lots of spaces between words, and we assign it to a PRE element's innerHTML (let's say the PRE has id=target).
var foo = "well,\n\nthis\nis\nsplit\ninto\nmany\nlines\nand\thas\ttabs\tin\tbetween\nalso lots of\ns p a c e s";
document.getElementById('target').innerHTML = foo;
One would expect that the white space (line breaks, tabs and spaces) should be preserved, and in fact that's what happens in FF and Opera. But Internet Explorer (tested on 6 and 7) normalizes the string, collapsing all adjacent white space intro a single space character. Here's how the PRE element looks in Firefox and Opera:
well, this is split into many lines and has tabs in between also lots of s p a c e s
And here's how it looks in Internet Explorer:
well, this is split into many lines and has tabs in between also lots of s p a c e s
I haven't been able to find a way to fix this, I think the only way around it is to use DOM methods instead of innerHTML to manipulate the PRE contents, but in some cases that's not necessarily an easy alternative (for example if there are HTML elements inside the string). If anyone has any new ideas on this, please share!
Posted in: English, Web, JavaScript
Tags: ie6, innerHTML
Getting innerHTML to work consistently in different browsers is
tricky. You may be able to get it to work by using BR elements and
nbsp entities, but the DOM methods usually behave more consistently
across browsers. I have been working on SHJS so that it will
preserve existing tags when highlighting (using DOM methods,
without using innerHTML). This feature is now available in version
0.6alpha1.
Great! As soon as I get a chance I'll try the new version. I actually missed out on 0.5, oops...
Thanks for this post! I just noticed the same thing in IE7 and was
amazed that I'd found yet *another* IE bug. Miserable. At least
finding this post lets me know I'm sane and not just missing
something. As a side effect of this bug, doing this: elem.innerHTML
= elem.innerHTML Completely removes all linebreaks. Stupid IE.
This pre bug is documented here:
http://webbugtrack.blogspot.com/2008/03/bug-165-dynamic-pre-population-fails-in.html
as well as a solution to the issue. You'll be happy to hear that
this is now fixed in IE9 (when it gets released)