Monday, July 17, 2006

When PRE does not mean PRE

So say you have a <pre> element. Say you need to update that <pre> with new contents. This should work, right?

document.getElementById('my_special_pre').innerHTML = some_big_block;

Well, almost. True, it does replace the contents of my_special_pre with some_big_block. However...IE for some reason simply forgets to preformat the white-space. Even if you assign the new content and then explicitly tell it you really do want that block to white-space: pre; - it still can't figure out that it needs to actually listen to newlines.

Now, I would at this point guess that IE parses the XML, basically ignoring the white-space, making some_big_block a single line of text without newlines. Except this corrects the behavior:

document.getElementById('my_special_pre').innerHTML = some_big_block.replace(/\n/g, "<br />\n");

Fucking brilliant. That hurt to write, so somebody please let me you know of a better way to correct this moronic IE "quirk."

*edited for a small grammer fix.

Labels: ,

6 Comments:

Anonymous Anonymous said...

Hi,
I've found the same problem and it seems that it can be overcome by using :
document.getElementById('my_special_pre').innerHTML = "<pre>" + some_big_block + "</pre>";

Still not perfect but it's another solution to the "replace" one.

7:37 PM  
Blogger The Hater said...

Unfortunately, putting a pre inside another pre doesn't follow the spec, even though your solution looks cleaner and would preformat all whitespace - not just line breaks like sticking br tags all over the place (which the spec doesn't seem to mind).

11:40 AM  
Blogger Neil Fraser said...

Thanks for that, it was a big help. I also had to add the following to prevent spaces from collapsing:
some_big_block.replace(/ /g, "\xA0 ").replace(/ /g, "\xA0 ");

12:28 AM  
Blogger Jorrit said...

Don't use innerHTML but DOM methods

4:28 PM  
Blogger The Hater said...

jorrit:

Completely correct, and thank you for adding that to this post after all of this time. Using DOM methods (at least, those IE actually fucking supports) instead of innerHTML not only makes things render a little more accurately, but it also helps prevent XSS (just, you know, for that added bonus).

12:15 AM  
Anonymous Anonymous said...

Another solution is:

element.innerHTML = newtext;
element.innerText = newtext;

IE supports both properties, but the second one overrides the first and doesn't perform the text normalization, so it looks correct. Browsers that don't support innerText (like Firefox) don't seem to have the same problem with innerHTML, so for them, the first line does the trick and the second does nothing (just sets a property on the element that the browser doesn't care about).

3:12 PM  

Post a Comment

<< Home