从 textarea 复制到 div,保留换行符

Posted

技术标签:

【中文标题】从 textarea 复制到 div,保留换行符【英文标题】:Copy from textarea to div, preserving linebreaks 【发布时间】:2013-04-16 10:16:06 【问题描述】:

我有一个<textarea> 和一个<div>(里面有一个<p>)。 在区域中输入文本时,<p> 会在 keyUp 时更新内容。

有没有办法保留 textarea 中的换行符(新行)并以某种方式让它们像 div/p 中的换行符一样工作?

</p><p> 替换双“新行”,这也可能吗?这接近于所见即所得的处理方式,但不希望这样做,这是一个非常小的项目。


这是我到目前为止所得到的。

$(".box textarea").keyup(function () 
  var value = $(this).val();  
  $('.box p').text(value);
);

【问题讨论】:

【参考方案1】:

您可能希望将 CSS 规则 white-space: prewhite-space: pre-wrap 添加到 .box p。这将按原样显示空白。

【讨论】:

这可能是最好的答案。 这应该是公认的答案。换行符是换行符,而不是新段落,并且使用 css 而不是 jQuery 始终是首选解决方案恕我直言...【参考方案2】:

你可以这样做:

$('.box textarea').keyup(function() 
    var value = $(this).val().replace(/\n/g, '<br/>');
    $(".box p").html(value);
);

这将替换 textarea 元素中的所有换行符 \n 并将它们全部替换为 html &lt;br/&gt; 标记,这样您就可以在 &lt;p&gt; 标记元素内的 textarea 中保留换行符。

这里的简单演示:

$('.box textarea').keyup(function() 
  $(".box p").html(this.value.replace(/\n/g, '<br/>'));
);
textarea,p 
  width: 90%;
  height: 80px;

p 
  border: 1px solid #eee;
  padding: 5px;
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="box">
  <textarea></textarea>
  <br/>
  <p></p>
</div>

如果您可以更改您的 css 文件,那么您也可以按照 @Explosion Pills 的建议尝试以下解决方案。即使您仍然必须在此处使用 jquery 代码将 textarea 输入的文本添加到 keyup 事件上的 p 标记,例如:

$('.box textarea').keyup(function() 
  $(".box p").html(this.value);  // replace is not needed here
);
textarea,p 
  width: 90%;
  height: 80px;

p 
  border: 1px solid #eee;
  padding: 5px;
  white-space: pre; // <--- This is the important part
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="box">
  <textarea></textarea>
  <br/>
  <p></p>
</div>

【讨论】:

在这种解决方案上徘徊了一个小时左右,但无法让它发挥作用。非常感谢! @Xavio 请注意,如果您的 textarea 包含带有 HTML 标签的文本(大概是您不想被解释),这将失败。当然,您可以将 &amp;lt;&amp;gt; 分别替换为 &amp;lt;&amp;gt;,但是使用 white-space CSS 规则会更简洁。 更糟糕的是,如果 textarea 的内容有可能受到恶意攻击者的影响,这将使您面临 HTML 注入和 XSS 攻击。经验法则是,从不混合未转义的用户输入和 HTML。【参考方案3】:

这里是最简单最安全的纯 jQuery 解决方案:

$(".box textarea").keyup(function () 
  var value = $(this).val();
  $('.box p').text(value).css('white-space', 'pre-wrap');
);

当然,如果您可以将.box p white-space: pre-wrap 添加到您的静态 CSS 样式中,那么您不需要使用 jQuery 进行注入。

(另请注意,white-space: pre-wrap 还会保留多个连续的空格,而不是折叠成一个空格。如果您不希望这样做,但仍想保留换行符,请改用 white-space: pre-line .)


附言。你应该永远将未转义的用户输入传递给.html()(例如当前接受的答案),因为如果输入包含任何HTML元字符,如&amp;&lt;,这样做会导致输出错误,并且如果输入可能受到恶意攻击者的影响,还可能使您面临 HTML 注入和跨站点脚本 (XSS) 攻击。

如果您绝对坚持不以任何形式使用 CSS white-space 属性,则需要先转义输入中的任何 HTML 元字符,然后再添加 &lt;br&gt; 标记。可能最简单和最安全的方法是让浏览器为您处理转义,例如像这样:

$(".box textarea").keyup(function () 
  var value = $(this).val();
  $('.box div.output').text(value).html(function (index, html) 
    return '<p>' + html.replace(/[^\S\n]+\n/g, '\n').replace(/\n\n+/g, '</p><p>').replace(/\n/g, '<br>') + '</p>';
  );
);

这将首先使用.text()将输入文本复制到目标元素中(它会自动对其进行HTML转义),然后修改生成的HTML代码以从行中删除尾随空格,以折叠多个连续换行进入段落分隔符,最后用&lt;br&gt;tags 替换单个换行。

(请注意,为了在输出中允许多个段落,目标元素应该是&lt;div&gt;,而不是&lt;p&gt;元素。将一个&lt;p&gt;元素嵌套在另一个元素中不是有效的HTML,并且可能在不同的浏览器上不会产生一致的结果。)

【讨论】:

【参考方案4】:

使用string.replace("\n", "&lt;br/&gt;") 将文本区域中的任何换行符替换为页面中的新行。

javascript

<script type="text/javascript">
function ta()

taValue = document.getElementById("ta").value;
taValue = taValue.replace("\n", "<br/>");
document.getElementById("tatext").innerHTML = taValue;

</script>

HTML:

<textarea id="ta" onkeyup="ta()"></textarea>
<div id="tatext"></div>

【讨论】:

-1:这只是 Palash Mondal 不完整答案的(不必要的冗长)副本。 ...也有同样的安全漏洞。 在这里发表评论的人我不明白为什么你认为这很糟糕。它有效,如果它是你所说的重复,那么请提供所谓的重复的链接,以便可以诚实地标记,而不仅仅是基于某人的提议或意见。 @RaphaelSchweikert 好的,我已经测试了这段代码,它可以工作。那么你说的所谓的“安全漏洞”是否消失了?如果您的意思是上面的评论是“重复”,那么请提供该重复来自的链接。 @IlmariKaronen @SeekLoad 我一直在谈论的是this 修订版。该答案的 cmets 中提到了 XSS 问题。

以上是关于从 textarea 复制到 div,保留换行符的主要内容,如果未能解决你的问题,请参考以下文章

如何将换行符从 HTML div 复制到 jQuery 中的 textarea?

将textarea的文本复制到带有换行符的div中

如何将自动换行添加到 EditorGUILayout.TextArea?

textarea:进行文本换行

我想扩JS替换textarea 中回车字符和空格

如何在textarea文本输入区内实现换行