jQuery 将换行符转换为 br 标签(类似于 nl2br)

115

我正在使用jQuery将一些文本区域的内容插入到一个li中。

我希望它可以保留换行符并在视觉上表现出来。

肯定有一种非常简单的方法来实现这个...


XSS注意:如果你正在这样做,那么很可能是直接混合了用户输入和<br/>标签,这意味着你要么显示换行符,要么显示<br/>标签,因此可能会受到XSS攻击,尤其是当你的输入来自站点上的其他用户时。 - user420667
9个回答

171

5
谢谢,这个完美地解决了问题。奇怪的是这不是 jQuery 的官方函数。 - gbhall
4
jQuery的设计目的并不是取代像replace这样的本地JavaScript函数,而是专注于CSS选择器链接和易用性!也许将来会有更好的版本;-) - Luca Filosofi
1
太棒了。帮助我解决了IE7不支持white-space: pre-wrap的问题。 - Kevin Pauli
那个正则表达式不是意味着如果一行以“>”结尾就不会添加BR吗?我知道在我的HTML中我使用>,但是用户生成的内容可能不太好用... - Dave Stein
有人在使用这个函数时也出现了两个 <br> 吗?这似乎是与 PHP 版本类似的问题,但我似乎无法解决它:http://stackoverflow.com/questions/11275006/double-line-breaks-with-pre-tag-and-nl2br - Adam Tal
显示剩余4条评论

97

你可以简单地执行以下操作:

textAreaContent=textAreaContent.replace(/\n/g,"<br>");

谢谢,这个方法有点用,但是它会把多个换行符看作一个。 - gbhall
4
我已更新它,现在它使用正则表达式,如果您想将多个换行符视为单个br,请更改正则表达式为:/\n+/g。 - mck89
谢谢。希望有人会发现你的答案有用,但下面的函数也可以工作。我感觉有点不好意思,因为你付出了更多的努力,但使用函数更加理想。 - gbhall
如果你遇到了错误 "x.replace is not a function",那么请使用 x.toString().replace。 - Vörös Imi

40

为了改变渲染而不是改变内容,以下CSS使每个换行符的行为类似于<br>

white-space: pre;
white-space: pre-line;

为什么有两个规则:pre-line 只影响换行符(感谢@KevinPauli的提示)。IE6-7和其他旧浏览器回退到更极端的pre,它也包括nowrap并呈现多个空格。这些和其他设置(pre-wrap)的详细信息在mozillacss-tricks上 (感谢@Sablefoste)。
虽然我通常不喜欢S.O.倾向于猜测问题而不是回答问题,但在这种情况下,用<br>标记替换换行符可能会增加使用未过滤的用户输入的注入攻击的风险。你正在越过一个明显的红线,每当你发现自己将.text()调用更改为.html()时,这意味着字面上的问题必须被解决。(感谢@AlexS强调了这一点。)即使你在当时排除了安全风险,未来的更改也可能无意中引入它。相反,这个CSS允许你使用更安全的.text()获得硬性换行符而不需要标记。

2
根据情况而定,这是最简单的解决方案,并且确实最好地回答了问题。您还可以考虑任何其他white-space:选项,例如pre-wrap。请参见https://css-tricks.com/almanac/properties/w/whitespace/。 - Sablefoste
这确实是最好的答案 - 字符串替换解决方案意味着需要使用.html()来设置内容,这反过来又会允许用户插入任意HTML,除非您事先过滤掉它。 - Alex S
@AlexS提到了关于.html()的危险之处,这是一个很好的观点,我尝试将其融入进去。 - Bob Stein

30

将以下代码放入你的代码中(最好是通用的JS函数库中):

String.prototype.nl2br = function()
{
    return this.replace(/\n/g, "<br />");
}

用法:

var myString = "test\ntest2";

myString.nl2br();

创建一个字符串原型函数允许您在任何字符串上使用this。


3
解决方案
使用以下代码
jQuery.nl2br = function(varTest){
  return varTest.replace(/(\r\n|\n\r|\r|\n)/g, "<br>");
};

2
这个JavaScript函数考虑使用插入或替换来处理交换。 (插入或替换HTML换行符)
/**
 * This function is same as PHP's nl2br() with default parameters.
 *
 * @param {string} str Input text
 * @param {boolean} replaceMode Use replace instead of insert
 * @param {boolean} isXhtml Use XHTML 
 * @return {string} Filtered text
 */
function nl2br (str, replaceMode, isXhtml) {

  var breakTag = (isXhtml) ? '<br />' : '<br>';
  var replaceStr = (replaceMode) ? '$1'+ breakTag : '$1'+ breakTag +'$2';
  return (str + '').replace(/([^>\r\n]?)(\r\n|\n\r|\r|\n)/g, replaceStr);
}

演示 - JSFiddle

JavaScript nl2br和br2nl函数


1
我写了一个小的 jQuery 扩展程序来实现这个功能:
$.fn.nl2brText = function (sText) {
    var bReturnValue = 'undefined' == typeof sText;
    if(bReturnValue) {
        sText = $('<pre>').html(this.html().replace(/<br[^>]*>/i, '\n')).text();
    }
    var aElms = [];
    sText.split(/\r\n|\r|\n/).forEach(function(sSubstring) {
        if(aElms.length) {
            aElms.push(document.createElement('br'));
        }
        aElms.push(document.createTextNode(sSubstring));
    });
    var $aElms = $(aElms);
    if(bReturnValue) {
        return $aElms;
    }
    return this.empty().append($aElms);
};

0

另一种在DOM中插入来自文本区域的文本并保留换行符的方法是使用Node.innerText属性,它表示节点及其后代的呈现文本内容。

作为getter,它近似于用户如果使用光标突出显示元素内容,然后复制到剪贴板时获得的文本。

该属性已成为标准,受到现代浏览器的广泛支持。 Can I Use:我发布此答案时全球范围内覆盖率达到97%。


0

为了改进@Luca Filosofi的答案,

如果需要的话,将正则表达式的开始子句改为/([^>[\s]?\r\n]?)还可以忽略标签后面紧跟换行符且有空格的情况,而不仅仅是标签紧跟换行符。


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