如何在element.textContent中插入新行或换行符?

98

假设我想动态创建一个新的DOM元素,并用JS字符串文字填充它的textContent/innerText属性。
这个字符串太长了,我想把它分成三个部分:

var h1 = document.createElement("h1");

h1.textContent = "This is a very long string and I would like to insert a carriage return HERE...
moreover, I would like to insert another carriage return HERE... 
so this text will display in a new line";

问题是,如果我写

h1.textContent = "...I would like to insert a carriage return here... \n";

它不起作用,可能因为浏览器将 '\n' 视为纯文本并按照此方式显示('\r' 也无效)。

另一方面,我可以更改 h1.innerHTML 而不是 textContent 并编写::

h1.innerHTML = "...I would like to insert a carriage return here...<br />";

这里可以使用<br />,但这样做会替换掉我的h1标签中的所有HTML内容,而不仅仅是文本内容,这不是我想要的结果.

有没有简单的方法来解决我的问题?
我不想创建多个块元素来使文本处于不同的行。


在标题元素中插入换行符的问题是,特别是如果视口很小,您无法确保标题不会在其他位置也换行。 - kennebec
你为什么想要添加换行符?你想看到渲染后的换行还是不想看? - Ciro Santilli OurBigBook.com
14个回答

186

我知道这个问题已经发布很久了。

我几天前遇到了类似的问题,需要将以json格式传递的值放置在tablecell中的contentText属性中。

由于值是以如下格式传递的:"text row1\r\ntext row2" 等等。

要在textContent中使用换行符,您必须使用\r\n,最后,我不得不使用css white-space: pre-line; (文本将在必要时换行和断行),一切都很好。

或者,您可以仅使用white-space: pre;,然后文本仅在换行符(在此情况下为\r\n)处换行。

因此,以下是一个示例,说明如何仅在换行符上换行:

var h1 = document.createElement("h1");

//setting this css style solving problem with new line in textContent
h1.setAttribute('style', 'white-space: pre;');

//add \r\n in text everywhere You want for line-break (new line)
h1.textContent = "This is a very long string and I would like to insert a carriage return \r\n...";
h1.textContent += "moreover, I would like to insert another carriage return \r\n...";
h1.textContent += "so this text will display in a new line";

document.body.appendChild(h1);


21
哈哈,这个回答是唯一正确的答案,但投票很少,直到现在也没有评论......似乎人们在这里无法正确阅读。问题是关于使用 textContent 的,使用 CSS 是解决它的另一种方法(可能是最干净的方法)。所以完美的答案。谢谢! - StanE
3
这个方法非常有效。我有一个文本域,需要通过换行符来分割文本,这就是解决方案。 - Robert
@Barrosy在问题中没有被命名为问题...这就像你告诉别人你根本无法访问完整的网站...有无数种可能性。这是对一个具体问题的具体回答。 - nelek
在花费了四个小时之后,我终于解决了字幕编辑的问题。 - Preet Singh
1
谢谢,伙计!没有任何问题! - hhsm95
显示剩余4条评论

33

我之前也遇到过这个问题。我找到了一个好的解决方案,就是使用回车符的 ASCII 表示(CODE 13)。JavaScript 有一个方便的功能叫做 String.fromCharCode(),它可以生成 ASCII 码的字符串版本,或多个由逗号分隔的代码。在我的情况下,我需要从一个长字符串生成 CSV 文件并将其写入文本区域。我需要能够剪切文本区域中的文本并将其保存到记事本中。当我尝试使用 <br /> 方法时,它不会保留回车符,但使用 fromCharCode 方法则可以保留回车符。请看下面的代码:

h1.innerHTML += "...I would like to insert a carriage return here..." + String.fromCharCode(13);
h1.innerHTML += "Ant the other line here..." + String.fromCharCode(13);
h1.innerHTML += "And so on..." + String.fromCharCode(13);
h1.innerHTML += "This prints hello: " + String.fromCharCode(72,69,76,76,79);

请参见此处有关该方法的更多详细信息:w3Schools-fromCharCode()

请参见此处ASCII码:ASCII Codes


26
这是完全错误的,多方面都有问题。13代表回车符号。它可以等效地写成'\r'('\r' === String.fromCharCode(13)返回true)。除非您使用的是Classic Mac,否则它不是换行符。换行符是ASCII 10或'\n'。然而,在HTML中,唯一的换行符是<br/>\r\n都被呈现为空格,除了在<pre>标签中。但是,innerTextinnerHtml会将这两个字符转换为<br/>以方便操作,所以它恰好能够运行。我没有查看规范,无法确定是否出于设计目的(我不会相信这么多)。 - Jan Hudec
8
旧的回答可能有误,但是这个回答并没有解决问题。我也遇到了相同的问题,而且问题是关于如何使用 textContent 而不是 innerHTML 的。 - StanE
1
针对将文本复制到剪贴板的特定情况,我已在我测试过的所有浏览器中完美地解决了这个问题。使用 '\n' 会根据浏览器而产生不同的结果。 - Valid
这是唯一对我有效的方法,我尝试了到目前为止发布在这个问题下的所有10种不同的解决方案。 - davea0511

12

nelek的回答是目前为止最好的,但它依赖于设置css值:white-space: pre,这可能不是理想的。

我想提供一个不同的解决方案,试图解决应该在这里提出的真正问题:

“如何将不受信任的文本插入DOM元素?”

如果您信任文本,为什么不只使用innerHTML?

domElement.innerHTML = trustedText.replace(/\r/g, '').replace(/\n/g, '<br>');

应该对所有合理情况都足够。

如果你决定使用.textContent而不是.innerHTML,那么这意味着你不信任即将插入的文本,对吗?这是一个合理的担忧。

例如,你有一个表单,用户可以创建一个帖子,在发布后,帖子文本被存储在你的数据库中,并在其他用户访问相关页面时附加到页面上。

如果你在这里使用innerHTML,你将面临安全漏洞。也就是说,用户可以发布像这样的内容:

<script>alert(1);</script>

如果你使用innerHTML,它不会触发警报,但它应该让你明白为什么使用innerHTML可能会有问题。一个更聪明的用户会发布

<img src="invalid_src" onerror="alert(1)" />

这将会触发每个访问该页面的其他用户的警报。现在我们有一个问题。更聪明的用户会在那个img样式上放置display: none,并使其将当前用户的cookie发布到跨域站点。恭喜,你所有用户的登录详细信息现在都暴露在互联网上。

因此,重要的是要理解,使用innerHTML并没有错,如果你只是使用它来构建模板,只使用自己信任的开发人员代码,那么它就是完美的。真正的问题应该是“如何将具有换行符的不受信任的用户文本附加到我的HTML文档中”。

This raises a question: which strategy do we use for newlines? do we use
elements?

s or s?

Here is a short function that solves the problem:

function insertUntrustedText(domElement, untrustedText, newlineStrategy) {
    domElement.innerHTML = '';
    var lines = untrustedText.replace(/\r/g, '').split('\n');
    var linesLength = lines.length;
    if(newlineStrategy === 'br') {
        for(var i = 0; i < linesLength; i++) {
            domElement.appendChild(document.createTextNode(lines[i]));
            domElement.appendChild(document.createElement('br'));
        }
    }
    else {
        for(var i = 0; i < linesLength; i++) {
            var lineElement = document.createElement(newlineStrategy);
            lineElement.textContent = lines[i];
            domElement.appendChild(lineElement);
        }
    }
}

You can basically throw this somewhere in your common_functions.js file and then just fire and forget whenever you need to append any user/api/etc -> untrusted text (i.e. not-written-by-your-own-developer-team) to your html pages.

usage example:

insertUntrustedText(document.querySelector('.myTextParent'), 'line1\nline2\r\nline3', 'br');

the parameter newlineStrategy accepts only valid dom element tags, so if you want [br] newlines, pass 'br', if you want each line in a [p] element, pass 'p', etc.


1
我该如何根据textContent显示额外的空格? 在这里不起作用。 - krave
为了支持更多的空格字符,您需要扩展该函数以熟悉它们。 - Aqo

6

h1.textContent 改为 h1.innerHTML,并使用 <br> 换行。


3
可能存在 XSS 漏洞。 - Christopher Adels

4
您可以将字符串连接起来...
h1.innerHTML += "...I would like to insert a carriage return here...<br />";
h1.innerHTML += "Ant the other line here... <br />";
h1.innerHTML += "And so on...<br />";

{{链接1:jsFiddle。}}


4
你可以使用正则表达式将 '\n' 或 '\n\r' 字符替换为 '<br />'。
你有以下内容:
var h1 = document.createElement("h1");

h1.textContent = "This is a very long string and I would like to insert a carriage return HERE...
moreover, I would like to insert another carriage return HERE... 
so this text will display in a new line";

你可以像这样替换你的字符:

h1.innerHTML = h1.innerHTML.replace(/\r\n?/g, '<br />');

请查看JavaScript参考手册,了解String和Regex对象:

http://www.w3schools.com/jsref/jsref_replace.asp

http://www.w3schools.com/jsref/jsref_obj_regexp.asp


Windows的换行符是\r\n,而不是\n\r - cdauth

3

以上的解决方法都没能帮到我。我想在一个 <p> 元素中添加换行和额外的文本。我通常使用 Firefox,但需要浏览器兼容性。我了解到只有 Firefox 支持 textContent 属性,只有 Internet Explorer 支持 innerText 属性,但两者都支持 innerHTML 属性。然而,无论将 <br />\n 还是 \r\n 添加到这些属性中,都没有换行。但是以下方法可以实现:

<html>
<body>
<script type="text/javascript">
  function modifyParagraph() {

  var p;
  p=document.getElementById("paragraphID");
  p.appendChild(document.createElement("br"));
  p.appendChild(document.createTextNode("Additional text."));
}    
</script>

<p id="paragraphID">Original text.</p>

<input type="button" id="pbutton" value="Modify Paragraph" onClick="modifyParagraph()" />
</body>
</html>

2
正如您所看到的,如果您再次阅读问题,它并不涉及 innerHTML,而是 textContent ... 用户没有关于 innerHTML 的问题... 那么,这个解决方案怎么正确呢?所有的解决方案都基于 innerHTML,但没有一个是基于 textContent... 它们是不同的。 - nelek
我认为使用textContent无法解决问题,因此我没有提供证据和文档来证明问题无法解决,而是提供了一种替代方案。在我看来,没有答案的问题是毫无意义的,而且通常答案并不在我们想象的地方。 - Slogmeister Extraordinaire
2
为什么不能解决?想象一下:我想为div元素设置contenteditable(现在不重要)...你会如何使用javascript解决这个带有换行符的问题?那么,在这种情况下,innerHTML的目的是什么?这就是为什么有些人使用textContent/innerText,而与innerHTML相关的一切都没有任何意义。这就是textContent/innerText的意义所在。而且,无论如何,正如你所看到的,这是可以解决的。 - nelek

3
使用element.innerHTML="some \\\\n some";

在我的使用情况下,最佳答案。 - GTS Joe
这没有任何意义。这只会将文本 some \\n some 放入元素中。此外,问题是关于 textContent 而不是 innerHTML - cdauth

1
我发现插入 \\n 有效。也就是说,你需要转义已经被转义的换行符。

1
通过在HTML中使用pre标签,我们可以直接使用标准转义序列字符串(如'\n'或'\r')进行格式化;
HTML:
<pre id="identifier"></pre>

JS:

const identifierDisplay = document.getElementById("identifier");
const identifierS = "Data to display. \n Some more data"
identifierDisplay.textContent = identifierS;

请注意字符串中的格式,任何制表符或空格都会直接反映出来。


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