从textarea获取文本时如何保留换行符?

Eth*_*orn 66 html javascript

当用户点击提交时,我在textarea中获得值.然后,我将此值放在页面的其他位置.但是,当我这样做时,它会丢失换行符,使得输出非常难看.

这是我访问的textarea:

<textarea id="post-text" class="form-control" rows="3" placeholder="What's up?" required></textarea>
Run Code Online (Sandbox Code Playgroud)

这是访问帖子并转录它的JavaScript代码.

var post = document.createElement('p');
var postText = document.getElementById('post-text').value;
post.append(postText);
var card = document.createElement('div');
card.append(post);
var cardStack = document.getElementById('#card-stack');
cardStack.prepend(card);
Run Code Online (Sandbox Code Playgroud)

当输入是这样的:

小组时间表:

周二练习@ 5楼(晚上8点 - 晚上11点)

星期四练习@ 5楼(晚上8点 - 晚上11点)

周日练习@(晚上9点到12点)

输出是:

小组时间表:星期二练习@ 5楼(晚上8点 - 晚上11点)周四练习@ 5楼(晚上8点 - 晚上11点)周日练习@(晚上9点 - 12点)

那么有没有办法保留换行符?

Ilm*_*nen 104

最简单的解决方案是使用以下CSS属性简单地为要插入文本的元素设置样式:

white-space: pre-wrap;
Run Code Online (Sandbox Code Playgroud)

此属性导致匹配元素中的空格和换行符以与a内部相同的方式处理<textarea>.也就是说,连续的空格不会折叠,并且线条会在显式换行符处断开(但如果它们超出元素的宽度,也会自动换行).

鉴于到目前为止发布的几个答案很容易受到HTML注入(例如因为他们分配了非转义用户输入innerHTML)或其他错误,让我举一个如何根据原始代码安全正确地做到这一点的示例:

document.getElementById('post-button').addEventListener('click', function () {
  var post = document.createElement('p');
  var postText = document.getElementById('post-text').value;
  post.append(postText);
  var card = document.createElement('div');
  card.append(post);
  var cardStack = document.getElementById('card-stack');
  cardStack.prepend(card);
});
Run Code Online (Sandbox Code Playgroud)
#card-stack p {
  background: #ddd;
  white-space: pre-wrap;  /* <-- THIS PRESERVES THE LINE BREAKS */
}
textarea {
  width: 100%;
}
Run Code Online (Sandbox Code Playgroud)
<textarea id="post-text" class="form-control" rows="8" placeholder="What's up?" required>Group Schedule:

Tuesday practice @ 5th floor (8pm - 11 pm)

Thursday practice @ 5th floor (8pm - 11 pm)

Sunday practice @ (9pm - 12 am)</textarea><br>
<input type="button" id="post-button" value="Post!">
<div id="card-stack"></div>
Run Code Online (Sandbox Code Playgroud)


请注意,与原始代码一样,上面的代码段使用append()prepend().在撰写本文时,这些功能仍被认为是实验性的,并不是所有浏览器都完全支持.如果您想要安全并与旧版浏览器保持兼容,您可以非常轻松地替换它们,如下所示:

  • element.append(otherElement)可以替换element.appendChild(otherElement);
  • element.prepend(otherElement)可以替换element.insertBefore(otherElement, element.firstChild);
  • element.append(stringOfText)可以替换element.appendChild(document.createTextNode(stringOfText));
  • element.prepend(stringOfText)可以替换element.insertBefore(document.createTextNode(stringOfText), element.firstChild);
  • 作为一个特殊的情况下,如果element为空,element.append(stringOfText)并且element.prepend(stringOfText)可以简单地被替换element.textContent = stringOfText.

这是与上面相同的代码段,但不使用append()prepend():

document.getElementById('post-button').addEventListener('click', function () {
  var post = document.createElement('p');
  var postText = document.getElementById('post-text').value;
  post.textContent = postText;
  var card = document.createElement('div');
  card.appendChild(post);
  var cardStack = document.getElementById('card-stack');
  cardStack.insertBefore(card, cardStack.firstChild);
});
Run Code Online (Sandbox Code Playgroud)
#card-stack p {
  background: #ddd;
  white-space: pre-wrap;  /* <-- THIS PRESERVES THE LINE BREAKS */
}
textarea {
  width: 100%;
}
Run Code Online (Sandbox Code Playgroud)
<textarea id="post-text" class="form-control" rows="8" placeholder="What's up?" required>Group Schedule:

Tuesday practice @ 5th floor (8pm - 11 pm)

Thursday practice @ 5th floor (8pm - 11 pm)

Sunday practice @ (9pm - 12 am)</textarea><br>
<input type="button" id="post-button" value="Post!">
<div id="card-stack"></div>
Run Code Online (Sandbox Code Playgroud)


PS.如果你真的想在使用CSS white-space属性的情况下这样做,另一种解决方案是用<br>HTML标签显式替换文本中的任何换行符.棘手的部分是,为了避免引入细微的错误和潜在的安全漏洞,您必须首先转义文本中的任何HTML元字符(至少&和/ <),然后再执行此替换.

可能最简单和最安全的方法是让浏览器为您处理HTML转义,如下所示:

var post = document.createElement('p');
post.textContent = postText;
post.innerHTML = post.innerHTML.replace(/\n/g, '<br>\n');
Run Code Online (Sandbox Code Playgroud)

document.getElementById('post-button').addEventListener('click', function () {
  var post = document.createElement('p');
  var postText = document.getElementById('post-text').value;
  post.textContent = postText;
  post.innerHTML = post.innerHTML.replace(/\n/g, '<br>\n');  // <-- THIS FIXES THE LINE BREAKS
  var card = document.createElement('div');
  card.appendChild(post);
  var cardStack = document.getElementById('card-stack');
  cardStack.insertBefore(card, cardStack.firstChild);
});
Run Code Online (Sandbox Code Playgroud)
#card-stack p {
  background: #ddd;
}
textarea {
  width: 100%;
}
Run Code Online (Sandbox Code Playgroud)
<textarea id="post-text" class="form-control" rows="8" placeholder="What's up?" required>Group Schedule:

Tuesday practice @ 5th floor (8pm - 11 pm)

Thursday practice @ 5th floor (8pm - 11 pm)

Sunday practice @ (9pm - 12 am)</textarea><br>
<input type="button" id="post-button" value="Post!">
<div id="card-stack"></div>
Run Code Online (Sandbox Code Playgroud)

请注意,虽然这将修复换行符,但它不会阻止HTML呈现器折叠连续的空格.通过用不间断的空格替换文本中的一些空格,可以(有点)模拟,但老实说,对于可以通过单行CSS轻松解决的问题,这变得相当复杂.

  • 白色空间:前线为我工作,因为预包装在第一行有缩进. (4认同)
  • 这似乎是最全面的答案.为什么投票失败?如果包含不正确的信息,请分享. (2认同)

Ste*_*eri 19

目标容器应该具有white-space:pre样式.试试下面.

<script>
function copycontent(){
 var content = document.getElementById('ta').value;
 document.getElementById('target').innerText = content;
}
</script>
<textarea id='ta' rows='3'>
  line 1
  line 2
  line 3
</textarea>
<button id='btn' onclick='copycontent();'>
Copy
</button>
<p id='target' style='white-space:pre'>

</p>
Run Code Online (Sandbox Code Playgroud)

  • 此代码易受HTML注入攻击,因为您将未转义的用户输入分配给`innerHTML`.在这种情况下,简单地用`textContent`替换`innerHTML`就可以解决它. (10认同)
  • `pre-wrap`或`pre-line`会更好.`pre`阻止换行,因此很长的文本行将强制水平滚动条. (8认同)
  • @IsmaelMiguel:这很奇怪 - 我是从IE 11发布的,它在这里工作得很好.[显然](https://msdn.microsoft.com/en-us/library/ff974773(V = vs.85)的.aspx)IE自9版本支持`textContent`. (3认同)
  • @IlmariKaronen这很奇怪......我没有意识到这一点.但如果你需要IE8,最好包含`innerText`. (2认同)

kol*_*odi 6

function get() {
  var arrayOfRows = document.getElementById("ta").value.split("\n");
  var docfrag = document.createDocumentFragment();
  
  var p = document.getElementById("result");
  while (p.firstChild) {
    p.removeChild(p.firstChild);
  }
  
  arrayOfRows.forEach(function(row, index, array) {
    var span = document.createElement("span");
    span.textContent = row;
    docfrag.appendChild(span);
    if(index < array.length - 1) {
      docfrag.appendChild(document.createElement("br"));
    }
  });

  p.appendChild(docfrag);
}
Run Code Online (Sandbox Code Playgroud)
<textarea id="ta" rows=3></textarea><br>
<button onclick="get()">get</button>
<p id="result"></p>
Run Code Online (Sandbox Code Playgroud)

您可以将textarea行拆分为数组:

var arrayOfRows = postText.value.split("\n");
Run Code Online (Sandbox Code Playgroud)

然后用它来生成更多p标签......

  • @IlmariKaronen说:这段代码不正确,因为你要将明文(`textarea.value`)分配给一个需要HTML(`innerHTML`)的属性.这是一种类型错误,会导致从文本损坏到安全漏洞等问题.您可以使用`document.createTextNode(text)`和`document.createElement('br')`来执行`appendChild`,而不是使用`innerHTML`. (3认同)
  • @misher:OP要求一种方法来保留换行符,而不是保留换行符的方法*和*允许HTML注入.当您寻求帮助来修复UI错误时获得免费的安全漏洞就像在您要求汉堡包时在小馅饼中获得免费的图钉.无论如何,由于你的"优化"代码似乎不再容易受到攻击,我已经删除了我的downvote. (3认同)
  • 提高效率的一个好方法是 [`document.createDocumentFragment`](https://developer.mozilla.org/en/docs/Web/API/Document/createDocumentFragment)。 (2认同)

小智 5

这是一个想法,因为文本框中可能有多个换行符:

 var text=document.getElementById('post-text').value.split('\n');
 var html = text.join('<br />');
Run Code Online (Sandbox Code Playgroud)

此 HTML 值将保留换行符。希望这可以帮助。