如何使用JavaScript在HTML中对TextArea设置最大长度限制

121

我希望拥有某种功能,使得当我输入

<textarea maxlength="50"></textarea>
<textarea maxlength="150"></textarea>
<textarea maxlength="250"></textarea>

它将自动对textArea施加maxlength属性限制。如果可能,请勿使用jQuery提供解决方案。

注意:如果我这样做,就可以实现此操作:

<textarea onkeypress="return imposeMaxLength(event, this, 110);" rows="4" cols="50">

function imposeMaxLength(Event, Object, MaxLen)
{
    return (Object.value.length <= MaxLen)||(Event.keyCode == 8 ||Event.keyCode==46||(Event.keyCode>=35&&Event.keyCode<=40))
}

引用自如何在HTML textarea上模拟HTML输入“maxlength”属性的最佳方法?

但是,我不想每次声明textarea时都写onKeyPress和onKeyUp。


4
文本区域的最大长度在HTML5中已经定义。目前它在Chrome浏览器中有效,但在Firefox中无效。 - Dave
16个回答

116
window.onload = function() { 
  var txts = document.getElementsByTagName('TEXTAREA'); 

  for(var i = 0, l = txts.length; i < l; i++) {
    if(/^[0-9]+$/.test(txts[i].getAttribute("maxlength"))) { 
      var func = function() { 
        var len = parseInt(this.getAttribute("maxlength"), 10); 

        if(this.value.length > len) { 
          alert('Maximum length exceeded: ' + len); 
          this.value = this.value.substr(0, len); 
          return false; 
        } 
      }

      txts[i].onkeyup = func;
      txts[i].onblur = func;
    } 
  };

}

3
Josh,看起来这个会起作用,但你能否解释一下这个东西会做什么?如果(/ ^ [0-9] +$ /。测试(txts [i]。getAttribute(“maxlength”))){ - Rakesh Juyal
2
我想我记得这个问题是什么:无论是FF还是IE(我认为是FF),当Javascript检查“value”属性时,返回的字符串与提交表单时发送回服务器的字符串不同!这与硬换行符是否插入回车字符有关。通过在客户端和服务器端使用一些调试代码很容易找出原因。 - Pointy
7
我将警报和截断值的顺序进行了调换 - 原本的顺序会导致在键盘松开时触发警报,使得控件失去焦点并触发 onblur,因为字段尚未被截断。 - GalacticCowboy
1
@JoshStodola - onblur 不会处理粘贴,直到用户从文本区域中点击出来。如果通过上下文菜单或浏览器菜单进行粘贴,则 onkeyup 不会处理它。如果您不需要筛选粘贴内容,则此方法可行。有关基于定时器的方法,请参见此答案http://stackoverflow.com/a/10390626/1026459 - Travis J
3
@JoshStodola - 的确不行。如果我在文本区域中粘贴了一整段内容,然后点击提交,但只看到其中的一小部分通过而没有任何响应,那么作为用户,这真的会让我很烦恼。 - Travis J
显示剩余8条评论

81

我知道你想避免使用jQuery,但由于此解决方案需要JavaScript,因此这个解决方案(使用jQuery 1.4)是最简洁和稳健的。

受Dana Woodman答案启发,但进行了改进:

与该答案不同的是: 更简化、更通用,使用jQuery.live,并且如果长度已经OK,则不设置val(在IE中导致箭头键正常工作,并且在IE中可以明显加速):

// Get all textareas that have a "maxlength" property. Now, and when later adding HTML using jQuery-scripting:
$('textarea[maxlength]').live('keyup blur', function() {
    // Store the maxlength and value of the field.
    var maxlength = $(this).attr('maxlength');
    var val = $(this).val();

    // Trim the field if it has content over the maxlength.
    if (val.length > maxlength) {
        $(this).val(val.slice(0, maxlength));
    }
});

编辑:使用on替代live,更新至jQuery 1.7+的版本。

// Get all textareas that have a "maxlength" property. Now, and when later adding HTML using jQuery-scripting:
$('textarea[maxlength]').on('keyup blur', function() {
    // Store the maxlength and value of the field.
    var maxlength = $(this).attr('maxlength');
    var val = $(this).val();

    // Trim the field if it has content over the maxlength.
    if (val.length > maxlength) {
        $(this).val(val.slice(0, maxlength));
    }
});

1
不错,Eirik。喜欢你使用 live(我都忘了它!)。 - Dana Woodman
5
我发现live()存在漏洞,因此jQuery已经将其弃用。请改用on()。如果你想知道为什么,请看这里:http://www.britishdeveloper.co.uk/2012/04/jquery-dont-use-bind-and-dont-use-live.html - BritishDeveloper
6
但是如果他们在中间进行编辑,这会导致最后一个字符被删除,而不是新添加的字符,对吗? - Joe Mabel
6
使用了 on() 方法,非常顺利。谢谢。这是稍作修改和优化的 jsfiddle 示例链接:http://jsfiddle.net/nXMqc/ - B-Money
6
切片的问题在于,如果您在中间插入字符,它们将被插入并且字符串将从结尾处截断。如果整个文本无法一次性显示,则可能会令人困惑。此外,使用val(..)函数更改值似乎会将光标移动到字符串的结尾。(如果您想在fiddle中使用现代浏览器测试这些内容,则需要删除maxlength属性 - 否则浏览器将强制执行限制)。 - Juha Palomäki
显示剩余2条评论

33

更新:使用 Eirik 的解决方案,使用 .live() 代替,因为它更加健壮。


即使您想要一个不使用 jQuery 的解决方案,我认为我还是可以提供一个类似于 jQuery 的解决方案,以供通过 Google 找到此页面并寻找类似于 jQuery 的解决方案的任何人使用:

$(function() {        
    // Get all textareas that have a "maxlength" property.
    $('textarea[maxlength]').each(function() {

        // Store the jQuery object to be more efficient...
        var $textarea = $(this);

        // Store the maxlength and value of the field.
        var maxlength = $textarea.attr('maxlength');
        var val = $textarea.val();

        // Trim the field if it has content over the maxlength.
        $textarea.val(val.slice(0, maxlength));

        // Bind the trimming behavior to the "keyup" event.
        $textarea.bind('keyup', function() {
            $textarea.val($textarea.val().slice(0, maxlength));
        });

    });
});

希望这对你们谷歌搜索者有所帮助...


1
keyup绑定的函数应为:$(this).val($(this).val().slice(0, maxlength)); - Brian Vallelunga
@brian 是的,你说得对。感谢你发现我的错误,已经修复了! - Dana Woodman
$(this).val(function(i, val){ return val.slice(0, maxlength) }); $(this).val(function(i, val){ return val.slice(0, maxlength) }); - Dima Bildin
这段代码仍然有用,因为在浏览器中换行符被计为1个字符,在服务器中则被计为2个字符... - bebbo

32

HTML5新增了maxlength属性到textarea元素中,如下所示:

<!DOCTYPE html>
<html>
    <body>
        <form action="processForm.php" action="post">
            <label for="story">Tell me your story:</label><br>
            <textarea id="story" maxlength="100"></textarea>
            <input type="submit" value="Submit">
        </form>
    </body>
</html>

目前在Chrome 13、FF 5以及Safari 5中支持此功能。毫不意外地,IE 9不支持此功能。(在Win 7上测试过)


5

该解决方案避免了IE浏览器在添加文本中间的字符时会删除最后一个字符的问题。同时,它也能够很好地运行在其他浏览器上。

$("textarea[maxlength]").keydown( function(e) {
    var key = e.which;  // backspace = 8, delete = 46, arrows = 37,38,39,40

    if ( ( key >= 37 && key <= 40 ) || key == 8 || key == 46 ) return;

    return $(this).val().length < $(this).attr( "maxlength" );
});

我的表单验证会处理用户可能粘贴(这似乎只在IE中出现问题)超过文本区域最大长度的文本。

4

这是我最近在网站上使用的一些调整过的代码。它已经改进,以向用户显示剩余字符的数量。

(再次对请求不使用jQuery的OP表示抱歉。但说真的,现在谁不用jQuery呢?)

$(function() {
    // Get all textareas that have a "maxlength" property.
    $("textarea[maxlength]").each(function() {

        // Store the jQuery object to be more efficient...
        var $textarea = $(this);

        // Store the maxlength and value of the field
        var maxlength = $textarea.attr("maxlength");

        // Add a DIV to display remaining characters to user
        $textarea.after($("<div>").addClass("charsRemaining"));

        // Bind the trimming behavior to the "keyup" & "blur" events (to handle mouse-based paste)
        $textarea.on("keyup blur", function(event) {
            // Fix OS-specific line-returns to do an accurate count
            var val = $textarea.val().replace(/\r\n|\r|\n/g, "\r\n").slice(0, maxlength);
            $textarea.val(val);
            // Display updated count to user
            $textarea.next(".charsRemaining").html(maxlength - val.length + " characters remaining");
        }).trigger("blur");

    });
});

未经过国际多字节字符测试,因此我不确定它在这些字符方面的工作方式。


3

还需要添加以下事件来处理在文本区域中粘贴的内容:

...

txts[i].onkeyup = function() {
  ...
}

txts[i].paste = function() {
  var len = parseInt(this.getAttribute("maxlength"), 10);

  if (this.value.length + window.clipboardData.getData("Text").length > len) {
    alert('Maximum length exceeded: ' + len);
    this.value = this.value.substr(0, len);
    return false;
  }
}

...

如果有人认为可以的话,能否将此内容添加到答案正文中?我还没有足够的积分来这样做。 - stusherwin
粘贴功能没有标准化。我相信它只在IE中有效。 - Josh Stodola
我更新了我的答案以处理粘贴情况。谢谢! - Josh Stodola

2

maxlength属性在Internet Explorer 10、Firefox、Chrome和Safari中被支持。

注意:<textarea>标签的maxlength属性不支持Internet Explorer 9及更早版本,也不支持Opera。

来自HTML maxlength属性w3schools.com

对于IE8或更早的版本,您需要使用以下内容。

//only call this function in IE
function maxLengthLimit($textarea){
    var maxlength = parseInt($textarea.attr("maxlength"));
    //in IE7,maxlength attribute can't be got,I don't know why...
    if($.browser.version=="7.0"){
        maxlength = parseInt($textarea.attr("length"));
    }
    $textarea.bind("keyup blur",function(){
        if(this.value.length>maxlength){
            this.value=this.value.substr(0,maxlength);
        }
    });
}

P.S.

<input> 标签的 maxlength 属性在所有主流浏览器中都被支持。

来自 HTML maxlength 属性 w3schools.com


2
你可以使用jQuery来使它变得简单明了。
JSFiddle 演示
<textarea id="ta" max="10"></textarea>

<script>
$("#ta").keypress(function(e){

    var k = e.which==0 ? e.keyCode : e.which;
    //alert(k);
    if(k==8 || k==37 || k==39 || k==46) return true;

    var text      = $(this).val();
    var maxlength = $(this).attr("max");

    if(text.length >= maxlength) {
        return false;   
    }
    return true;
});
</script>

这段代码在 FirefoxGoogle ChromeOpera 浏览器中测试通过。


我担心当处理程序被执行时,text会被填充为textarea在更新之前的“值”。这意味着您的测试应该是 if( text.length +1 > maxlength) {return false;}。否则,只能在:/中放入maxlength - 1个字符。 - Stphane
你的小提琴让用户输入一个字符。在我看来,你的测试应该是 if(text.length+1 > maxlength) 或者 if(text.length >= maxlength) ... - Stphane
当我复制和粘贴内容时,它并没有按预期工作。 - Ranjit Kumar

1
与修剪textarea值相比,更好的解决方案。
$('textarea[maxlength]').live('keypress', function(e) {
    var maxlength = $(this).attr('maxlength');
    var val = $(this).val();

    if (val.length > maxlength) {
        return false;
    }
});

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