textarea的换行与空格问题
# 简介
# 各系统的换行问题 回车符\r和换行符\n
一、概念:
换行符‘\n’和回车符‘r’
(1)换行符就是另起一行 --- '\n' 10 换行(newline)
(2)回车符就是回到一行的开头 --- '\r' 13 回车(return)
所以我们平时编写文件的回车符应该确切来说叫做回车换行符
CR: 回车(Carriage Return) \r LF: 换行(Line Feed) \n
二、应用:
(1)在微软的MS-DOS和Windows中,使用“回车CR('\r')”和“换行LF('\n')”两个字符作为换行符;
(2)Windows系统里面,每行结尾是 回车+换行(CR+LF),即“\r\n”;
(3)Unix系统里,每行结尾只有 换行LF,即“\n”;
(4)Mac系统里,每行结尾是 回车CR 即'\r'。
Mac OS 9 以及之前的系统的换行符是 CR,从 Mac OS X (后来改名为“OS X”)开始的换行符是 LF即‘\n',和Unix/Linux统一了。
三、影响:
(1)一个直接后果是,Unix/Mac系统下的文件在Windows里打开的话,所有文字会变成一行;
(2)而Windows里的文件在Unix/Mac下打开的话,在每行的结尾可能会多出一个^M符号。
(3)Linux保存的文件在windows上用记事本看的话会出现黑点。
四、可以相互转换:
在linux下,命令unix2dos 是把linux文件格式转换成windows文件格式,命令dos2unix 是把windows格式转换成linux文件格式。
在不同平台间使用FTP软件传送文件时, 在ascii文本模式传输模式下, 一些FTP客户端程序会自动对换行格式进行转换. 经过这种传输的文件字节数可能会发生变化.
如果你不想ftp修改原文件, 可以使用bin模式(二进制模式)传输文本。
一个程序在windows上运行就生成CR/LF换行格式的文本文件,而在Linux上运行就生成LF格式换行的文本文件。
# 空格显示不正常
这是因为浏览器显示机制,会将连续多个空格显示成1个空格。
在这些示例中,HTML和JSX中的空格是一样的
<div>Hello•World</div>
<div>•Hello•World</div>
<div>••Hello•World</div>
<div>•••Hello•World•••</div>
<div>Hello•••World</div>
123456
2
3
4
5
6
7
虽然JSX在在HTML中渲染多个空格,但是浏览器仍然会压缩空格序列。(假定CSS的white-space属性是默认值:normal)。
<div>
••Hello•World•••
</div>
// 开头和结尾处的空格被移除
<div>Hello•World</div>
12345
2
3
4
5
6
有两种解决方案:
- 使用
 
空格转义字符来添加空格; - css样式设置为
white-space:pre;
# 换行显示不正常
项目中遇到后台返回数据存在换行符却无法正常换行;比如:textarea元素中编辑带有格式的文本,无法按照原格式输出。举个例子,一个页面有textarea元素,一个div,一个按钮,当点击按钮时,将textarea中的值显示在div中。
<html>
<body>
<textarea cols="10" rows="10"></textarea>
<div></div>
<button type="button">点击</button>
</body>
</html>
<script type="text/javascript">
$('button').click(function(){
$('div').html($('textarea').val());
})
</script>
2
3
4
5
6
7
8
9
10
11
12
# 方式一:利用pre
1、在textarea输出的div中添加如下样式:
.content { white-space: pre;}
2、利用
标签来输出textarea的内容:
<pre>这是textarea中的内容....</pre>
该方式的优缺点:
优点: 不需要区别浏览器, 正则校验替换, 保存输入的符号
缺点: 但是超出长度部分不会折行显示, 在同行显示, 需要添加 white-space的样式; 详见方法三;
white-space: pre-wrap || pre-line;
pre 标签样式, 可能会改变预期样式 字体大小, 颜色, 字体类型等, 需要全局设置初始值
# 方式二:将 \n\r 替换成 br 标签
利用正则,写法如下:
input.replace(/\r/ig, '').replace(/\n/ig, '<br/>')
注意: 需要 dangerouslySetInnerHTML: { __html: text} 解析。
该方式的优缺点:
优点: 可设置自动换行,可不修改样式, 如果统一处理包裹标签有可能会影响
缺点: dangerouslySetInnerHTML 有 XSS 漏洞, 建议使用 html escape 处理
import _ from 'lodash';
const createHtml = encodedHtml => ({
__html: encoded(createHtml)
});
function encoded(html) {
return _.escape(html).replace(/\r/g, '').replace(/\n/g, '<br/>')
}
export function newlineReplaceBr(input) {
if (input) {
return h.span({
dangerouslySetInnerHTML: createHtml(input)
})
}
else {
return ''
}
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
使用JS字符串对象的方法replace
将textarea中所有的\n和\s分别替换成
<br />
和 
<script type="text/javascript">
$('button').click(function(){
var new_str = $('textarea').val().replace(/\n|\r\n/g,'<br>').replace(/\s/g,' ');
$('div').html(new_str);
})
</script>
//根据Value格式化为带有换行、空格格式的HTML代码
var getFormatCode=function(strValue){
return strValue.replace(/\r\n/g, '<br/>').replace(/\n/g, '<br/>').replace(/\s/g, ' ');
}
2
3
4
5
6
7
8
9
10
<div
dangerouslySetInnerHTML={{
__html: formatMessage({ id: 'JavaComponent.outputTips' }),
// '(1)多条语句要用;号分开:<br />\n' +
// '(2)支持系统变量:如 SELECT * FROM table1 WHERE time=${time_id}<br />\n' +
// '(3)最后sql需要返回执行结果判断 (-1:执行失败,0:执行成功,1:重新等待)\n',
}}
/>
2
3
4
5
6
7
8
# 方式三:在元素上white-space
所有浏览器都支持 white-space 属性。white-space 属性设置如何处理元素内的空白, 换行;
只需把CSS样式设置成white-space: pre-wrap;
- pre-wrap 保留空白符序列,但是正常地进行换行
- pre-line 合并空白符序列,但是保留换行符
- pre: **空白会被浏览器保留, 在遇到换行符或者
<br>
**元素时才会换行, 类似 HTML 中的<pre>
标签
# white-space解释
white-space的值:
normal:连续的空白符会被合并,换行符会被当作空白符来处理。填充line盒子时,必要的话会换行。
nowrap:和 normal 一样,连续的空白符会被合并。但文本内的换行无效。
pre:连续的空白符会被保留。在遇到换行符或者
<br>
元素时才会换行。pre-wrap:连续的空白符会被保留。在遇到换行符或者
<br>
元素,或者需要为了填充line盒子时才会换行。pre-line:连续的空白符会被合并。在遇到换行符或者
<br>
元素,或者需要为了填充line盒子时会换行。
white-space各个值的表现如下:
.texty span {
display: inline-block;
white-space: pre-wrap;
}
2
3
4
是否能发挥作用 | 换行符 | 空格 | 自动换行 | nbsp; |
---|---|---|---|---|
normal | × | ×(合并) | √ | √ |
nowrap | × | ×(合并) | × | √ |
pre | √ | √ | × | √ |
pre-wrap | √ | √ | √ | √ |
pre-line | √ | ×(合并) | √ | √ |
# word-break、word-wrap、white-space的区别
- white-space,控制空白字符的显示,同时还能控制是否自动换行。它有五个值:
normal | nowrap | pre | pre-wrap | pre-line
- word-break,控制单词如何被拆分换行。它有三个值:
normal | break-all | keep-all
- word-wrap(overflow-wrap)控制长度超过一行的单词是否被拆分换行,是
word-break
的补充,它有两个值:normal | break-word
# white-space
详见上面解释
# word-break
从这个名字可以知道,这个属性是控制单词如何被拆分换行的。它有三个值:
normal | break-all | keep-all
。
word-break:keep-all
所有“单词”一律不拆分换行,注意,我这里的“单词”包括连续的中文字符(还有日文、韩文等),或者可以理解为只有空格可以触发自动换行
word-break:break-all
所有单词碰到边界一律拆分换行,不管你是incomprehensibilities
这样一行都显示不下的单词,还是long
这样很短的单词,只要碰到边界,都会被强制拆分换行。所以用word-break:break-all
时要慎重呀。
# word-wrap(overflow-wrap)
word-wrap
又叫做overflow-wrap
:
word-wrap 属性原本属于微软的一个私有属性,在 CSS3 现在的文本规范草案中已经被重名为 overflow-wrap 。 word-wrap 现在被当作 overflow-wrap 的 “别名”。 稳定的谷歌 Chrome 和 Opera 浏览器版本支持这种新语法。
这个属性也是控制单词如何被拆分换行的,实际上是作为word-break
的互补,它只有两个值:normal | break-word
;
break-word
终于达到了上文我们希望的效果,只有当一个单词一整行都显示不下时,才会拆分换行该单词。
所以我觉得overflow-wrap
更好理解好记一些,overflow,只有长到溢出的单词才会被强制拆分换行!
设置强行换行
无效的原因:元素中设置的white-space是norwrap,所以无法换行。
解决:
white-space:normal
word-wrap:break-word
2
# 参考链接
https://juejin.im/post/6844903667863126030