Chrome使用maxlength属性计算textarea中的字符错误

时间:2012-04-05 14:52:26

标签: javascript html google-chrome textarea maxlength

以下是一个例子:

$(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(一行一个字符),直到浏览器允许。 完成后,请保留textarea,js代码也会计算字符。

所以在我的情况下,在chrome阻止我之前我只能输入7个字符(包括空格)。虽然maxlength属性的值是10:

imgur

10 个答案:

答案 0 :(得分:35)

以下是如何让您的javascript代码与浏览器认为在textarea中的字符数相匹配:

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。

答案 1 :(得分:27)

当涉及maxlength时,您的回车被认为是2个字符。

1\r\n
1\r\n
1\r\n
1

但似乎javascript只能\r\n中的一个(我不确定哪一个)只能加上 7

答案 2 :(得分:14)

由于未知原因,jQuery始终将<textarea>值中的所有换行符转换为单个字符。也就是说,如果浏览器为换行符提供\r\n,则jQuery会确保\n的返回值仅为.val()

对于“maxlength”,Chrome和Firefox都会以相同的方式计算<textarea>个标签的长度。

但是,HTTP规范坚持将换行符表示为\r\n。因此,jQuery,webkit和Firefox都错了。

结果是,如果您的服务器端代码确实具有固定的字段值最大大小,则<textarea>标签上的“maxlength”几乎没用。

编辑 - 此时(2014年末)看起来Chrome(38)的行为正常。然而,Firefox(33)仍然不会将每个硬回车计为2个字符。

答案 3 :(得分:13)

基于Pointy的上述答案,似乎正确的方法是将所有新行计为两个字符。这样可以跨浏览器对其进行标准化,并匹配发布时发送的内容。

因此,我们可以按照规范更换所有出现的回车符,而不是新行,并且所有新行后面都没有回车符,并带有回车 - 换行符对。

var len = $('#test').val().replace(/\r(?!\n)|\n(?!\r)/g, "\r\n").length;

然后使用该变量显示textarea值的长度,或限制它,依此类推。

答案 4 :(得分:3)

看起来javascript正在考虑新行字符的长度。

尝试使用:


var x = $('#test').val();

x = x.replace(/(\r\n|\n|\r)/g,"");    

$('#length').html(x.length);

我在你的小提琴中使用它并且它正在工作。希望这会有所帮助。

答案 5 :(得分:1)

这是因为新行实际上是2个字节,因此长2个。 JavaScript没有这样看,所以它只计数1,总计7(3个新行)

答案 6 :(得分:1)

这是一个更通用的解决方案,它会覆盖jQuery&#39; val&#39;功能。将很快将这个问题变成博客文章并链接到这里。

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);
    }
};

答案 7 :(得分:0)

var value = $('#textarea').val();
var numberOfLineBreaks = (value.match(/\n/g)||[]).length;
$('#textarea').attr("maxlength",500+numberOfLineBreaks);

完全适用于谷歌已经在IE中必须避免脚本!在IE中,'break-line'只计算一次,所以在IE中避免这个解决方案!

答案 8 :(得分:0)

如果你想获得文本区域的剩余内容长度,那么你可以在包含换行符的字符串上使用匹配。

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 :(得分:0)

Textareas在浏览器中仍未完全同步。我注意到两个主要问题:回车和字符编码

回车

默认情况下,操作为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的内容中解析:

  

安西码:&amp;#13;&amp;#10;

<textarea>Line one.&#13;&#10;Line two.</textarea>

3)从键盘输入键

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