HTML textarea 忽略第一个换行符,为啥?

Posted

技术标签:

【中文标题】HTML textarea 忽略第一个换行符,为啥?【英文标题】:HTML textarea ignores 1st new line character, why?HTML textarea 忽略第一个换行符,为什么? 【发布时间】:2013-03-09 21:34:18 【问题描述】:

你能解释一下为什么吗:

<script type="text/javascript">
   document.write("<textarea cols='10' rows='10'>" + "\nhello\nbabe\n" + "</textarea>");
</script>

渲染一个底部有一个新行的文本区域,但顶部没有新行

测试过 IE8、FF11、Safari 5.1、Chrome 24

这不是 JS 问题,即使你在页面中编写 html 也会得到相同的结果,即

<textarea cols='10' rows='10'>
hello
babe
</textarea>

第一个新行还是不见了!!!

我需要在顶部添加另一个新行才能显示:

document.write("<textarea cols='10' rows='10'>" + "\n\nhello\nbabe\n" + "</textarea>");

【问题讨论】:

你用 标签试过了吗? "\n" 不会被视为 textarea 值,而是被视为 html 断线 【参考方案1】:

在 XHTML 内部编写时使用适当的实体。

<textarea>&#13;hello</textarea>

如果文本节点以空格(空格、换行)开头,HTML 解析器将忽略它。将新行编码为适当的 HTML 实体会强制解析器对其进行确认。

&#13; == carriage return

【讨论】:

它不适用于 IE8,但适用于 Chrome 24、Safari 和 FF。我认为这是 IE8 错误。 @Marco Demaio - IE8 可能也需要换行符 ( ),因为 Windows 认为新行 "\n" 是回车 + 换行符 ( ) . 你成就了我的一天。 Textarea 已经杀死了一个小时) 这对我有用。在脚本中: s = s.replace(/^\n/ , "")【参考方案2】:

回答“为什么”这个问题。这在 HTML 5 规范中指定,该章节描述了如何从 HTML 文档中的标签创建 DOM 树。

在当前的 HTML 5 生活标准中是“12.2 解析 HTML 文档”>“12.2.6 树构造”>“12.2.6.4 解析 HTML 内容中标记的规则”>"12.2.6.4.7 The "in body" insertion mode".

(在 HTML 5.2 中,同一部分的编号为 8.2.5.4.7)。

向下滚动以找到“标签名称为“textarea”的起始标签”

标签名称为“textarea”的开始标签 运行以下步骤: 1. 为令牌插入一个 HTML 元素。 2. 如果下一个标记是 U+000A LINE FEED (LF) 字符标记,则忽略该标记并继续下一个标记。 (为方便创作,忽略 textarea 元素开头的换行符。) 3. 将分词器切换到 RCDATA 状态。 ...

该算法只处理 LF 字符,因为 CR 字符是 handled earlier。

(从历史上看,查看过时的 HTML 4.01 规范: 它的Chapter 17.7 "The TEXTAREA element" 有一个示例,显示文本区域的文本内容从新行开始。 Appendix B.3.1 Line breaks(信息性)解释说这种行为源自 SGML。)

如今,在 HTML 5 中,&lt;/textarea&gt; 结束标记之前的换行符不会被忽略。

【讨论】:

【参考方案3】:

如果可能,更改您的代码以将 textarea 预定义为 html,然后改为这样编写字符串:

HTML:

<textarea cols='10' rows='10' id='test'></textarea>

脚本:

document.getElementById('test').innerHTML = '\nhello\nbabe\n';

这应该保留空白。或者,您可以添加一个 css 规则:

textarea 
    white-space:pre;
    

一个可以玩的小提琴:http://jsfiddle.net/RFLwH/1/

更新:

在 IE8 中测试的 OP 不起作用 - 这似乎是此浏览器的限制/错误。如果您在顶部手动插入换行符,IE8 确实使用 CR+LF,但是当设置为编程时,浏览器会完全忽略它。

将此添加到 html 以进行测试:

<span onclick="this.innerHTML = escape(document.getElementById('test').innerHTML);">
    Get textarea content
</span>

可以看到返回的字符串是:

 %0D%0Ahello%20babe%20

表示 CR+LF 在那里(其他换行符转换为空格 - 但在开头插入空格也无济于事)。我想您对此行为无能为力。浏览器已经过时(但不幸的是,它仍然被广泛使用,所以如果这是必要的,这对那些用户来说可能是个问题)。

【讨论】:

它不适用于 IE8,但适用于 Chrome 24、Safari 和 FF。我认为这是 IE8 错误。 是的,这并不奇怪。我对 ie8 进行了测试(在本地,因为小提琴也不能在 ie8 中显示)并在顶部手动插入换行符并将文本取出并转义以查看其中包含的内容。它 do 插入 /r/n 那里,但是当从 javascript 设置它时,它只是完全忽略它。猜猜这没什么关系:-/【参考方案4】:

在第一个“\n”之前添加一个空格,如下所示:

<script type="text/javascript">
   document.write("<textarea cols='10' rows='10'>" + " \nhello\nbabe\n" + "</textarea>");
</script>

<textarea cols='10' rows='10'> <!-- whitespace here -->
hello
babe
</textarea>

否则将无法正常工作。


更新: 稍后在您的服务器端,您可以通过执行删除第一个空格

$str = ltrim ($str,' ');

$str2 = substr($str, 4);

如果是 php

【讨论】:

脚本中的空白用空格渲染第一行。这不好,可以将 textarea 中的数据发送到服务器,然后将它们保存到数据库中,并增加没有人需要的空间。【参考方案5】:

它应该是顶部的\n\rdocument.write("&lt;textarea cols='10' rows='10'&gt;" + "\n\rhello\nbabe\n" + "&lt;/textarea&gt;");

jsbin

【讨论】:

对我来说,使用'\n\r' 而不是'\r\n' 是多么奇特!【参考方案6】:

我终于完成了这个服务器端解决方案:

在 textarea 中输出之前加倍前导(仅第一个!)nl 符号:

if(str_startswith("\r\n",$value))

    $value = "\r\n".$value;             
elseif(str_startswith("\n",$value))

    $value = "\n".$value;
elseif(str_startswith("\r",$value))

    $value = "\r".$value;


function str_startswith($start, $string)

  if(mb_strlen($start)>mb_strlen($string))
    return FALSE;
  return (mb_substr($string, 0,mb_strlen($start))==$start);

【讨论】:

以上是关于HTML textarea 忽略第一个换行符,为啥?的主要内容,如果未能解决你的问题,请参考以下文章

<textarea> 占位符的换行符 \n 在 Safari 上被忽略

为啥我从 textarea 中提取换行符的方法是使用 \r [重复]

textarea:进行文本换行

JavaFX TextArea如何使用自动换行符设置文本

textarea 按回车为啥不换行

Textarea 忽略输入但需要触发保存按钮