如何将新行/回车符插入element.textContent?

use*_*489 55 javascript string escaping carriage-return

虽然听起来很傻,但我还是没有找到合适的答案.

假设我想动态创建一个新的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";
Run Code Online (Sandbox Code Playgroud)

问题是,如果我写

h1.textContent = "...I would like to insert a carriage return here... \n";
Run Code Online (Sandbox Code Playgroud)

它不起作用,可能是因为浏览器认为'\n'是纯文本并且显示为纯文本(\ r \n也不起作用).

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

h1.innerHTML = "...I would like to insert a carriage return here...<br />";
Run Code Online (Sandbox Code Playgroud)

这里<br />会完成这项工作,但这样做不仅会取代文本内容,还会取代我h1的所有HTML内容,这不是我想要的.

有没有一种简单的方法来解决我的问题?
我不打算创建多个块元素只是为了让文本在不同的行上.
任何想法将不胜感激.
提前致谢.

nel*_*lek 87

我很久以前就知道这个问题.

几天前我遇到了类似的问题,以json格式传递Web服务的价值并将其放入table cell contentText.

因为值以格式传递,例如, "text row1\r\ntext row2"等等.

对于textContent你必须使用的新行\r\n,最后,我不得不使用csswhite-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);
Run Code Online (Sandbox Code Playgroud)

  • 大声笑,这个答案是这个问题的唯一正确答案,但是它还没有被投票,直到现在都没有评论......似乎这里的人无法正确阅读.问题是关于使用`textContent`.使用CSS是解决它的另一种方法(也许是最干净的).如此完美的答案.谢谢! (14认同)
  • 这是最好的答案. (5认同)
  • 正是这就像一个魅力。我有一个 textarea 用新行分割文本,这是解决方案 (2认同)

JBa*_*mer 31

我刚才遇到了这个问题.我发现一个很好的解决方案是使用回车的ASCII表示(代码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);
Run Code Online (Sandbox Code Playgroud)

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

有关ASCII代码,请参见此处:ASCII代码

  • 在许多层面上,这是完全错误的.13是回车.它可以等效地写成`'\ r'`(`'\ r'=== String.fromCharCode(13)`给出true).除非你使用的是经典Mac,否则它是换行符的错误字符.换行符是ASCII 10,或者是''\n'`.但是在HTML中,唯一的换行是`<br/>`.除了`<pre>`之外,`\ r``和`\n`都被渲染为空格.然而,`innerText`和`innerHtml`为了方便起见将两个字符转换为`<br/>`,所以它恰好起作用.我没有检查规格是否按设计工作(我不会相信那么多). (20认同)
  • 旧的答案和我可能是错的,但这是如何解决这个问题的呢?我有同样的问题,问题是关于使用`textContent`,而不是`innerHTML`. (6认同)

Aqo*_*Aqo 12

nelek 的答案是迄今为止发布的最好的答案,但它依赖于设置 css 值:white-space: pre,这可能是不可取的。

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

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

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

domElement.innerHTML = trustedText.replace(/\r/g, '').replace(/\n/g, '<br>');
Run Code Online (Sandbox Code Playgroud)

对于所有合理的情况应该足够了。

如果您决定应该使用 .textContent 而不是 .innerHTML,则意味着您不信任要插入的文本,对吧?这是一个合理的担忧。

例如,您有一个表单,用户可以在其中创建帖子,发布帖子后,帖子文本将存储在数据库中,然后每当其他用户访问相关页面时就会附加到页面。

如果您在这里使用innerHTML,则会出现安全漏洞。即,用户可以发布类似的内容

<script>alert(1);</script>
Run Code Online (Sandbox Code Playgroud)

如果您使用innerHTML,它不会触发警报,但它应该让您了解为什么使用innerHTML 会出现问题。更聪明的用户会发布

<img src="invalid_src" onerror="alert(1)" />
Run Code Online (Sandbox Code Playgroud)

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

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

这就提出了一个问题:我们对换行符使用哪种策略?我们使用
元素吗?

是还是?

这是一个解决该问题的简短函数:

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);
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

你基本上可以把它扔到你的 common_functions.js 文件中的某个地方,然后只要你需要附加任何 user/api/etc -> 不受信任的文本(即不是由你自己的开发团队编写的)到你的 html 页面。

用法示例:

insertUntrustedText(document.querySelector('.myTextParent'), 'line1\nline2\r\nline3', 'br');
Run Code Online (Sandbox Code Playgroud)

参数 newlineStrategy 只接受有效的 dom 元素标签,因此如果您想要 [br] 换行符,请传递 'br',如果您想要 [p] 元素中的每一行,请传递 'p' 等。


小智 6

更改为h1.textContenth1.innerHTML使用<br>以转到新行。

  • 可能的xss漏洞 (3认同)

小智 5

您可以使用正则表达式将'\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";
Run Code Online (Sandbox Code Playgroud)

你可以像这样替换你的角色:

h1.innerHTML = h1.innerHTML.replace(/\n\r?/g, '<br />');
Run Code Online (Sandbox Code Playgroud)

检查String和Regex对象的javascript参考:

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

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


Ica*_*rus 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 />";
Run Code Online (Sandbox Code Playgroud)

js小提琴。