views:

2162

answers:

4

I'm using Prototype's PeriodicalUpdater to update a div with the results of an ajax call. As I understand it, the div is updated by setting its innerHTML.

The div is wrapped in a <pre> tag. In Firefox, the <pre> formatting works as expected, but in IE, the text all ends up on one line.

Here's some sample code found here which illustrates the problem. In Firefox, abc is on different line than def; in IE it's on the same line.

    <html>
    <head>
      <title>IE preformatted text sucks</title>
    </head>
    <body>
      <pre id="test">
        a b c
        d e f
      </pre>
      <script type="text/javascript"><!--
      var textContent = document.getElementById("test").innerText;
      textContent = textContent.replace("a", "<span style=\"color:red;\">a</span>");
      document.getElementById("test").style.whiteSpace = "pre";
      document.getElementById("test").innerHTML = textContent;
      --></script>
    </body>
    </html>

Anyone know of a way to get around this problem?

+6  A: 

Setting innerHTML fires up an HTML parser, which ignores excess whitespace including hard returns. If you change your method to include the <pre> tag in the string, it works fine because the HTML parser retains the hard returns.

You can see this in action by doing a View Generated Source after you run your sample page:

<PRE id="test" style="WHITE-SPACE: pre"><SPAN style="COLOR: red">a</SPAN> b c d e f </PRE>

You can see here that the hard return is no longer part of the content of the <pre> tag.

EndangeredMassa
+3  A: 

Generally, you'll get more consistent results by using DOM methods to construct dynamic content, especially when you care about subtle things like normalization of whitespace. However, if you're set on using innerHTML for this, there is an IE workaround, which is to use the outerHTML attribute, and include the enclosing tags.

if(test.outerHTML)
    test.outerHTML = '<pre id="test">'+textContent+'</pre>';
else
    test.innerHTML = textContent;

This workaround and more discussion can be found here: http://stackoverflow.com/questions/195363/inserting-a-newline-into-a-pre-tag-ie-javascript

Jordan Liggitt
A: 

or you could

if( el.innerText ) { el.innerText = val ; } else { el.innerHTML = val ; }

martin
A: 

Or, I suppose, you could rewrite it 'the Python way', i.e.:

el.innerText && el.innerText = val || el.innerHTML = val;