<pre class="prettyprint-override"> tag loses line breaks when setting innerHTML in IE

Я использую Prototype PeriodicalUpdater для обновления div с результатами вызова ajax. Как я понимаю, div обновляется установкой innerHTML.

div завернут в тег <pre>. В Firefox форматирование <pre> работает так, как ожидалось, но в IE текст заканчивается на одной строке.

Здесь приведен пример кода здесь, который иллюстрирует проблему. В Firefox abc находится на другой строке, чем def; в IE это в той же строке.

    <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>

Кто-нибудь знает, как обойти эту проблему?

Ответ 1

Настройка innerHTML запускает HTML-парсер, который игнорирует лишние пробелы, включая жесткие возвраты. Если вы измените свой метод, чтобы включить <pre> тег в строке, он отлично работает, потому что парсер HTML сохраняет твердые результаты.

Вы можете увидеть это в действии, выполнив View Generated Source после запуска вашей страницы с образцом:

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

Здесь вы можете видеть, что жесткий возврат больше не является частью содержимого <pre> тег.

Ответ 2

или вы можете

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

Ответ 3

Как правило, вы получите более последовательные результаты, используя методы DOM для создания динамического контента, особенно если вы заботитесь о тонких вещах, таких как нормализация пробелов. Однако, если вы используете для этого innerHTML, существует обходной путь IE, который должен использовать атрибут outerHTML и включать теги, охватывающие.

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

Это обходное решение и более подробное обсуждение можно найти здесь: Вставка новой строки в предварительный тег (IE, Javascript)

Ответ 4

Не знаю, было ли это предложено раньше, но решение, которое я нашел для сохранения пробела, новых строк и т.д. при использовании innerHTML в теге pre, - это вставить еще один тег 'pre' в текст

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

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

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

Кажется, I.E. выполняет синтаксический анализ текста перед выполнением innerHTML. Вышеприведенное приводит к тому, что анализатор не оставляет текст внутри дополнительного тега pre. Имеет смысл с тех пор, что должен делать парсер. также работает с FF.

Ответ 5

Он также может быть переписан "Путь Python", т.е.:

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