Вставка новой строки в тег pre (IE, Javascript)

В IE, когда я вставляю текст в тег <pre>, новые строки игнорируются:

<pre id="putItHere"></pre>

<script>
function putText() {
   document.getElementById("putItHere").innerHTML = "first line\nsecond line";
}
</script>

Использование \r\n вместо простого \n не работает.

<br/> работает, но вставляет лишнюю пустую строку в FF, что неприемлемо для моих целей.


person Itay Maman    schedule 12.10.2008    source источник
comment
‹br /› у меня не добавляется дополнительная строка в Firefox.   -  person Vincent McNabb    schedule 12.10.2008
comment
Я тоже, я думаю, он оставил \n после этого, отсюда и мой ответ.   -  person GavinCattell    schedule 12.10.2008
comment
Я думал, что одна из целей jQuery заключается в том, чтобы абстрагироваться от различий между браузерами и версиями. Если бы я хотел новое (сломанное) поведение IE, я бы использовал .innerHTML = "..." вместо .html("..."). Я что-то пропустил?   -  person    schedule 03.12.2011


Ответы (11)


Эти отчеты об ошибках и комментарии quirksmode.org о поведении innerHTML Internet Explorer может помочь:

"IE применяет нормализацию HTML к данным, назначенным свойству innerHTML. Это приводит к неправильному отображению пробелов в элементах, которые должны сохранять форматирование, таких как ‹pre› и ‹textarea›. "

person splattne    schedule 12.10.2008

Это работает в IE?

document.getElementById("putItHere")
    .appendChild(document.createTextNode("first line\nsecond line"));

Я протестировал его с Firefox, и он работает. :-)

person Chris Jester-Young    schedule 12.10.2008
comment
Работал как шарм, мне нужно было сделать полную html-инъекцию в тег pre. Я тестировал все обратно в IE6. - person Chad Scira; 08.12.2011
comment
Помогло и в моем случае, и это быстрое решение. - person Leo; 14.05.2012
comment
Это отлично сработало для меня в IE8, гораздо более элегантно, чем код Javascript, записывающий HTML-теги. - person Steve Ferguson; 10.07.2013

Обходной путь можно найти на странице, на которую есть ссылка в принятом ответе. Для удобства использования вот оно:

if (elem.tagName == "PRE" && "outerHTML" in elem)
{
    elem.outerHTML = "<PRE>" + str + "</PRE>";
}
else
{
    elem.innerHTML = str;
}
person Edward Wilde    schedule 12.12.2008
comment
Спасибо за публикацию соответствующей части ссылки. - person ; 03.12.2011

<br/> должен выводить только одну строку во всех браузерах. Конечно, удалите \n, код должен быть:

document.getElementById("putItHere").innerHTML = "first line<br/>second line";
person GavinCattell    schedule 12.10.2008

Содержимое внутри тега <pre> не должно считаться HTML.

На самом деле смысл тега <pre> в том, что он отображает форматированный текст.

Использование свойства innerText — правильный способ изменить содержимое тега <pre>.

document.getElementById("putItHere").innerText = "first line\nsecond line";
person Samuel Kim    schedule 12.10.2008
comment
Правда, это будет нормально работать в IE, но обратите внимание, что innerText недоступен в Firefox - методы манипулирования DOM, вероятно, будут более надежным решением в этом случае, например, ответ Криса Джестера-Янга с использованием appendChild и document.createTextNode. - person J c; 12.10.2008

IE9 не нормализует белый цвет пробелы, в отличие от своих предшественников.

Вы должны тестировать поддержку, а не ориентироваться на какой-то конкретный браузер. Например...

var t = document.createElement(elem.tagName);
t.innerHTML = "\n";

if( t.innerHTML === "\n" ){
    elem.innerHTML = str;
}
else if("outerHTML" in elem)
{
    elem.outerHTML = "<"+elem.tagName+">" + str + "</"+elem.tagName+">";
}
else {
    // fallback of your choice, probably do the first one.
}
person Drew    schedule 10.03.2011

Я считаю это.

Я обнаружил, что IE использует \r\n, а Fx (другие) использует \n

var newline;
if ( document.all ) newline = '\r\n';
else newline = '\n';

var data = 'firstline' + newline + 'second line';
document.getElementById("putItHere").appendChild(document.createTextNode(data));

Для плагина TinyMCE (редактор wysiwyg), который я однажды сделал, я использовал режим редактирования BR i и очистил его при отправке и т. Д.

Этот код перебирает все элементы BR внутри элементов PRE и заменяет BR символами новой строки.

Обратите внимание, что код основан на TinyMCE API, но его легко написать с помощью стандартного Javascript.

Очистить:

        var br = ed.dom.select('pre br');
        for (var i = 0; i < br.length; i++) {
          var nlChar;
          if (tinymce.isIE)
            nlChar = '\r\n';
          else
            nlChar = '\n';

          var nl = ed.getDoc().createTextNode(nlChar);
          ed.dom.insertAfter(nl, br[i]);
          ed.dom.remove(br[i]);
        }

Удачи!

person Community    schedule 12.10.2008
comment
Это на самом деле лучшее решение, которое я нашел здесь. Вот что у меня получилось, что на самом деле невероятно близко к тому, как обычно работает .innerText. Вот что у меня получилось: element.innerText = ""; element.appendChild(document.createTextNode(textContent)); - person Karl White; 30.01.2017

Если вы не хотите использовать externalHTML, вы также можете сделать следующее для IE, если дополнительный тег pre не является проблемой:

 if(isIE)
     document.getElementById("putItHere").innerHTML = "<pre>" + content+"</pre>";
 else
     document.getElementById("putItHere").innerHTML = content;
person Vivek Jani    schedule 27.04.2010

Я обнаружил, что innerHTML обрабатывается до того, как он применяется к элементу, поэтому ‹br› становится новой строкой, а несколько пробелов удаляются.

Чтобы сохранить необработанный текст, вы должны использовать, например, nodeValue;

document.getElementById('pre_id').firstChild.nodeValue='    white space \r\n ad new line';
person Community    schedule 05.05.2009
comment
Я думаю, что это лучший ответ, чем принятый. Принятый ответ не сохраняет атрибуты в теге ‹pre›, и сделать это будет еще сложнее. - person ; 04.12.2011
comment
Оказывается, это не работает в IE9. Усвоенный урок заключается в том, чтобы не публиковать сообщения, когда вы устали, расстроены и тестируете полдюжины браузеров. - person ; 06.12.2011

Вот очень небольшая поправка к ответу Эдварда Уайльда, которая сохраняет атрибуты тега ‹pre›.

if (elem.tagName == "PRE" && "outerHTML" in elem) {
    var outer = elem.outerHTML;
    elem.outerHTML = outer.substring(0, outer.indexOf('>') + 1) + str + "</PRE>";
}
else {
    elem.innerHTML = str;
}
person Community    schedule 06.12.2011

if (typeof div2.innerText == 'undefined')
    div2.innerHTML = value;
else
    div2.innerText = value;

это сработало для меня.

person Community    schedule 05.03.2009