13

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?

Rob W
  • 341,306
  • 83
  • 791
  • 678
MCS
  • 22,113
  • 20
  • 62
  • 76

5 Answers5

18

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
  • 17,208
  • 8
  • 55
  • 79
5

or you could

if (el.innerText) {
    el.innerText = val;
} else {
    el.innerHTML = val;
}
phihag
  • 278,196
  • 72
  • 453
  • 469
martin
  • 67
  • 1
  • 1
  • 1
    This answer is wrong. Why does it have 7 up-votes ? With innerHTML you will lose all linebreaks. You did not understand the question. – Elmue Jan 19 '16 at 22:08
5

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: Inserting a newline into a pre tag (IE, Javascript)

Community
  • 1
  • 1
Jordan Liggitt
  • 16,933
  • 2
  • 56
  • 44
1

Don't know if this has been suggested before, but the solution I found for preserving white space, newlines, etc when doing an innerHTML into a 'pre' tag is to insert another 'pre' tag into the text:

<pre id="pretag"></pre>

TextToInsert = "lots of text with spaces and newlines";

document.getElementById("pretag").innerHTML = "<pre>" + TextToInsert + "</pre>";

Seems I.E. does parse the text before doing the innerHTML. The above causes the parser to leave the text inside the additional 'pre' tag unparsed. Makes sense since that's what the parser is supposed to do. also works with FF.

0

It could also be rewritten 'the Python way', i.e.:

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

ccpizza
  • 28,968
  • 18
  • 162
  • 169