向<pre>标签(使用IE、Javascript)插入换行符

16

在IE中,当我向<pre>标签中插入文本时,换行符会被忽略:

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

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

使用\r\n而不是简单的\n是不起作用的。

<br/>可以工作,但在FF中会插入一个额外的空行,这对我的目的来说是不可接受的。


1
在Firefox中,<br />对我来说并不会添加额外的行。 - Vincent McNabb
我也是这样认为的,我猜他在后面留了一个换行符,因此我的回答是这样的。 - GavinCattell
我认为jQuery的一个重要目标之一是抽象出浏览器和版本之间的差异。如果我想要新的(有问题的)IE行为,我会使用.innerHTML =“…”而不是.html(“…”)。我错过了什么吗? - user287466
11个回答

13

这些关于Internet Explorer的innerHTML行为的quirksmode.org漏洞报告和评论可能会有所帮助:

"IE对分配给innerHTML属性的数据应用HTML规范化。这会导致在应该保留格式的元素(如<pre>和<textarea>)中显示空格不正确。"


7

这个在IE中能正常工作吗?

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

我用Firefox测试了一下,它可以正常工作。:-)


1
运作得非常好,我需要将完整的HTML注入到pre标签中。我甚至测试了IE6。 - Chad Cache
在我的情况下也有帮助,而且这是一个快速的解决方法。 - Leo
这对我在IE8中非常有效,比让Javascript代码编写HTML标签更优雅。 - Steve Ferguson
真的节省了我的时间,做得很好! - Vayn

5
解决方法可以在被接受的答案链接的页面中找到。为了方便使用,这里提供链接:
if (elem.tagName == "PRE" && "outerHTML" in elem)
{
    elem.outerHTML = "<PRE>" + str + "</PRE>";
}
else
{
    elem.innerHTML = str;
}

1
感谢您发布链接的相关部分。 - user287466

4

<pre>标签内的内容不应被视为HTML代码。

实际上,<pre>标签的作用是显示格式化文本。

使用innerText属性是修改<pre>标签内容的正确方法。

document.getElementById("putItHere").innerText = "first line\nsecond line";

1
没错,在IE中这个方法可以正常工作,但请注意innerText在Firefox中不可用。在这种情况下,DOM操作方法可能是更健壮的解决方案,比如Chris Jester-Young的答案使用appendChild和document.createTextNode。 - J c

4

<br/> 在所有浏览器中只应输出一行。当然,也要删除 \n,代码应该是:

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

2

与其前身不同,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.
}

1

如果您不想使用outerHTML,对于IE浏览器,您也可以采用以下方法,如果额外的pre标签不是问题:

 if(isIE)
     document.getElementById("putItHere").innerHTML = "<pre>" + content+"</pre>";
 else
     document.getElementById("putItHere").innerHTML = content;

1
我发现innerHTML在应用于元素之前会被处理,因此<br>会变成换行符,并且多个空格会被删除。
为了保留原始文本,您必须使用nodeValue,例如;
document.getElementById('pre_id').firstChild.nodeValue='    white space \r\n ad new line';

我认为这是一个比被采纳的答案更好的答案。被采纳的答案没有保留<pre>标签中的属性,这样做甚至需要更多的工作。 - user287466
结果发现这在IE9中不起作用。得到的教训是不要在疲惫、沮丧和测试半打浏览器时发布。 - user287466

1

我想是这样的。

我发现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编辑模式,并在提交等过程中进行清理。

此代码循环遍历 PRE 元素内的所有 BR 元素并将 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]);
        }

祝你好运!


这实际上是我在这里找到的最佳解决方案。以下是我最终得出的结果,它与.innerText正常工作的方式非常接近。这就是我最终得出的结果: element.appendChild(document.createTextNode(textContent));``` - Karl White

1

这里是对Edward Wilde答案的微小调整,可以保留

标签上的属性。

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

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接