Chrome 在 textarea 中使用 maxlength 属性计数错误的字符
Posted
技术标签:
【中文标题】Chrome 在 textarea 中使用 maxlength 属性计数错误的字符【英文标题】:Chrome counts characters wrong in textarea with maxlength attribute 【发布时间】:2012-04-19 07:55:05 【问题描述】:这是一个例子:
$(function()
$('#test').change(function()
$('#length').html($('#test').val().length)
)
)
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<textarea id=test maxlength=10></textarea>
length = <span id=length>0</span>
用行(一行一个字符)填充文本区域,直到浏览器允许。 完成后离开textarea,js代码也会计算字符。
所以在我的情况下,在 chrome 阻止我之前,我只能输入 7 个字符(包括空格)。虽然 maxlength 属性的值为 10:
【问题讨论】:
类似:***.com/q/12924591/266535 或者或者可能是这样的:***.com/questions/11839413/… 【参考方案1】:以下是如何让您的 javascript 代码匹配浏览器认为文本区域中的字符数量:
http://jsfiddle.net/FjXgA/53/
$(function ()
$('#test').keyup(function ()
var x = $('#test').val();
var newLines = x.match(/(\r\n|\n|\r)/g);
var addition = 0;
if (newLines != null)
addition = newLines.length;
$('#length').html(x.length + addition);
)
)
基本上,您只需计算文本框中的总换行符,然后将每个换行符的字符数加 1。
【讨论】:
也可以写成:$('#length').html(x.replace(/(\r\n|\n|\r)/g, '--').length);
这在 Firefox 中会出错,因为它将换行符计为 1 个字符
@Stalinko 我刚刚在 Firefox、Chrome、IE、Edge 和 Opera 中进行了测试。它似乎在所有这些中都起作用。换行符将长度加 2。这是你看到的还是你的意思是别的?
@Tim,即使脚本正确显示长度,如果已经存在回车,它也允许输入更多字符。输入 2 个回车后,我可以输入 12 个字符。【参考方案2】:
当涉及到 maxlength 时,您的回车每个被视为 2 个字符。
1\r\n
1\r\n
1\r\n
1
但似乎 javascript 只能是 \r\n
之一(我不确定是哪一个),它只能加起来 7。
【讨论】:
我已经在 Chrome 和 Firefox 中记录了关于这个问题的错误;它似乎已在 Chrome 的最新版本中修复。 @Pointy 我在 Chrome 的开发版 (19.0.1084.1
) 中,但我仍然有这个问题。
是的,我也这么认为。但是为什么js不把回车算作2个字符呢?有没有办法让它做到这一点?
当文本区域的内容实际发布时,嵌入的换行必须作为 CR LF 对传输。因此,正确的做法是让浏览器报告内容的长度,就像换行符花费 2 个字符一样。
@Neal 哦,好吧,我正在对 OP 发表评论。这似乎是一个非常严重的问题,因为它使“maxlength”属性基本上无用。【参考方案3】:
根据上面 Pointy 的回答,似乎正确的方法是将所有新行计为两个字符。这将使其跨浏览器标准化,并与发布时发送的内容相匹配。
所以我们可以按照规范,用回车 - 换行对替换所有出现的回车不跟新行,以及所有新行不跟回车。
var len = $('#test').val().replace(/\r(?!\n)|\n(?!\r)/g, "\r\n").length;
然后使用那个变量来显示textarea值的长度,或者限制它,等等。
【讨论】:
【参考方案4】:由于未知的原因,jQuery 总是将 <textarea>
值中的所有换行符转换为单个字符。也就是说,如果浏览器给它\r\n
换行,jQuery 会确保它在.val()
的返回值中只是\n
。
Chrome 和 Firefox 都以相同的方式计算 <textarea>
标签的长度,以达到“最大长度”的目的。
但是,HTTP 规范坚持将换行符表示为 \r\n
。因此,jQuery、webkit 和 Firefox 都犯了这个错误。
如果你的服务器端代码确实有一个固定的最大字段值大小,那么<textarea>
标签上的“maxlength”几乎没有用。
edit — 在这一点上(2014 年末),Chrome (38) 的行为似乎正常。但是,Firefox (33) 仍然不将每个硬返回计为 2 个字符。
【讨论】:
尖尖 -- I just asked a question related to this OP 对-o - 我会复制到那里。 您似乎在说.val()
返回错误(1 个字符),但浏览器正确地将其视为 2 个字符,因此 maxlength
将考虑每个换行符的 2 个字符。如果是这种情况,并且您的后端数据库有一个固定的最大值,我看不出maxlength
有什么用处,因为它正确计算了将保存在数据库中的字符数。
@wired_in hi 再次 :) 问题是内置的 maxlength
检查确实 not 考虑到 CR 字符。这意味着内置的 maxlength
将允许 textarea 在客户端中包含比允许的更多的 actual 字符。因此,如果您有一个长度为 500 个字符的数据库字段,并且您说 maxlength=500
,则发布的表单可能包含 超过 500 个字符的值。因此该属性是无用的。
@Pointy 这与这个问题相矛盾。 OP 说他有一个 textarea,maxlength
为 10,但是当他在 textarea 中输入时,他只能输入 7 个字符(每个换行符包括 1 个字符)。这清楚地表明 maxlength
正在考虑每个新行的 2 个字符。我自己的测试证实了这一点......【参考方案5】:
看起来 javascript 也在考虑换行符的长度。
尝试使用:
var x = $('#test').val();
x = x.replace(/(\r\n|\n|\r)/g,"");
$('#length').html(x.length);
我在你的小提琴中使用它并且它正在工作。希望这会有所帮助。
【讨论】:
【参考方案6】:这是因为一个新行实际上是 2 个字节,因此是 2 个长。 JavaScript 不这样看,因此它只会计数 1,总共 7(3 个新行)
【讨论】:
【参考方案7】:这是一个更通用的解决方案,它覆盖了 jQuery 'val' 函数。很快将把这个问题写成一篇博文并在此处链接。
var originalVal = $.fn.val;
$.fn.val = function (value)
if (typeof value == 'undefined')
// Getter
if ($(this).is("textarea"))
return originalVal.call(this)
.replace(/\r\n/g, '\n') // reduce all \r\n to \n
.replace(/\r/g, '\n') // reduce all \r to \n (we shouldn't really need this line. this is for paranoia!)
.replace(/\n/g, '\r\n'); // expand all \n to \r\n
// this two-step approach allows us to not accidentally catch a perfect \r\n
// and turn it into a \r\r\n, which wouldn't help anything.
return originalVal.call(this);
else
// Setter
return originalVal.call(this, value);
;
【讨论】:
btw 很棒的博文【参考方案8】:如果要获取文本区域的剩余内容长度,则可以在包含换行符的字符串上使用 match。
HTML:
<textarea id="content" rows="5" cols="15" maxlength="250"></textarea>
JS:
var getContentWidthWithNextLine = function()
return 250 - content.length + (content.match(/\n/g)||[]).length;
【讨论】:
【参考方案9】:var value = $('#textarea').val();
var numberOfLineBreaks = (value.match(/\n/g)||[]).length;
$('#textarea').attr("maxlength",500+numberOfLineBreaks);
已经在 IE 中的 google 上完美运行必须避免脚本!在 IE 中,'break-line' 只计算一次,因此请避免在 IE 中使用此解决方案!
【讨论】:
粘贴失败。【参考方案10】:文本区域在浏览器之间仍未完全同步。我注意到两个主要问题:回车和字符编码
回车
默认为 2 个字符 \r\n(Windows 风格)。
问题在于 Chrome 和 Firefox 会将其视为一个字符。您也可以选择它来观察有一个隐形字符被选中作为空格。
在此处找到解决方法:
var length = $.trim($(this).val()).split(" ").join("").split('\n').join('').length;
Jquery word counts when user type line break
另一方面,Internet Explorer 会将其计为 2 个字符。
他们的代表是:
二进制: 00001101 00001010
十六进制: 0D0A
,在 UTF-8 中表示为 2 个字符,maxlength 计为 2 个字符。
HTML 实体可以是
1) 由 javascript 代码创建:
<textarea id='txa'></textarea>
document.getElementById("txa").value = String.fromCharCode(13, 10);
2) 从textarea的内容解析:
Ansi 代码:
<textarea>Line one. Line two.</textarea>
3) 从键盘 Enter 键插入
4) 定义为文本框的多行内容
<textarea>Line one.
Line two.</textarea>
字符编码
像 textarea 这样的输入字段的字符编码独立于页面的字符编码。如果您打算计算字节数,这很重要。因此,如果您有一个元标头来定义页面的 ANSI 编码(每个字符 1 个字节),则文本框的内容仍然是 UTF-8,每个字符 2 个字节。
这里提供了字符编码的解决方法:
function htmlEncode(value)
// Create a in-memory div, set its inner text (which jQuery automatically encodes)
// Then grab the encoded contents back out. The div never exists on the page.
return $('<div/>').text(value).html();
function htmlDecode(value)
return $('<div/>').html(value).text();
HTML-encoding lost when attribute read from input field
【讨论】:
以上是关于Chrome 在 textarea 中使用 maxlength 属性计数错误的字符的主要内容,如果未能解决你的问题,请参考以下文章
在 Chrome 和 Firefox 中使用换行符对 textarea 进行不同的 maxlength 验证
JavaScript 更新 textarea 冻结 Chrome,但不冻结 Firefox
如何限制 chrome 中的最大 textarea 宽度和高度或如何禁用 textarea 调整大小
css3“新”样式的flexbox无法在chrome中拉伸textarea
取消chrome浏览器下input和textarea的默认样式
<foreignObject> 中的 <textarea> 在 Chrome 中按预期处理,但在 Firefox 中没有