限制ContentEditable div中的字符数

我在我的web应用程序中使用contenteditable div元素,我正在想出一个解决scheme,以限制在该区域允许的字符数量,一旦限制被打中,尝试input字符根本什么都不做。 这是我迄今为止:

var content_id = 'editable_div'; //binding keyup/down events on the contenteditable div $('#'+content_id).keyup(function(){ check_charcount(content_id, max); }); $('#'+content_id).keydown(function(){ check_charcount(content_id, max); }); function check_charcount(content_id, max) { if($('#'+content_id).text().length > max) { $('#'+content_id).text($('#'+content_id).text().substring(0, max)); } } 

这样可以将字符数限制为由“max”指定的数字,但是一旦区域的文本由jquery .text()函数设置,光标就会将其自身重置为该区域的开始。 因此,如果用户继续打字,新input的字符将被插入到文本的开头,文本的最后一个字符将被删除。 所以真的,我只是需要一些方法来保持光标在contenteditable区域的文本的末尾。

如何将event对象传递给你的函数,如果达到最大值,调用e.preventDefault()

 var content_id = 'editable_div'; max = 10; //binding keyup/down events on the contenteditable div $('#'+content_id).keyup(function(e){ check_charcount(content_id, max, e); }); $('#'+content_id).keydown(function(e){ check_charcount(content_id, max, e); }); function check_charcount(content_id, max, e) { if(e.which != 8 && $('#'+content_id).text().length > max) { // $('#'+content_id).text($('#'+content_id).text().substring(0, max)); e.preventDefault(); } } 

虽然,您可能需要做更多的事情来允许用户执行“删除”之类的操作。


编辑:

增加了对“删除”键的支持。


编辑2:

此外,你可能会摆脱keyup处理程序。 keydown应该够了。

一个简单的方法来实现这一点:

 <div onkeypress="return (this.innerText.length <= 256)" contenteditable="true"> 

首先,这种事情让用户感到恼火:我会build议,而不是做一些类似于StackOverflow的注释字段,它允许你input尽可能多或less的字符,告诉你input了多less个字符以及是否太多或太less,并拒绝让您提交长度无效的评论。

其次,如果你真的必须限制文本的长度,如果内容太长,每次击键都replace<div>的全部内容是不必要的,并且会使得编辑器在较慢的机器上无响应。 我build议处理keypress事件,并简单地使用preventDefault()事件(或在IE中,设置事件的returnValuetrue ,假设您使用attachEvent )来防止插入的字符。 这不会阻止用户粘贴文本,因此您需要处理paste事件(Opera或Firefox中不存在<3,因此您需要某种基于轮询的解决scheme) 。 由于您无法预先访问正在粘贴的内容,因此您无法知道粘贴是否会超过字符数限制,因此您需要设置一个计时器以便很快再次检查长度之后贴。 所有这一切,第一个select似乎比我更可取。

以下解决scheme还考虑了控制键(对应于不可打印的字符)。

 //Maximum number of characters var max = 200; $('#editable_div').keydown(function(e) { var keycode = e.keyCode; //List of keycodes of printable characters from: //http://stackoverflow.com/questions/12467240/determine-if-javascript-e-keycode-is-a-printable-non-control-character var printable = (keycode > 47 && keycode < 58) || // number keys keycode == 32 || keycode == 13 || // spacebar & return key(s) (if you want to allow carriage returns) (keycode > 64 && keycode < 91) || // letter keys (keycode > 95 && keycode < 112) || // numpad keys (keycode > 185 && keycode < 193) || // ;=,-./` (in order) (keycode > 218 && keycode < 223); // [\]' (in order) if (printable) { //Based on the Bala Velayutham's answer return $(this).text().length <= max; } }); 

这是我通过jQuery绑定完成的方式,只需将一个属性data-input-length添加到内容可编辑元素即可轻松实现。 只需在文档的任何位置添加JavaScript代码。

 $(document).ready(function(){ // Excempt keys(arrows, del, backspace, home, end); var excempt = [37,38,39,40,46,8,36,35]; // Loop through every editiable thing $("[contenteditable='true']").each(function(index,elem) { var $elem = $(elem); // Check for a property called data-input-length="value" (<div contenteditiable="true" data-input-length="100">) var length = $elem.data('input-length'); // Validation of value if(!isNaN(length)) { // Register keydown handler $elem.on('keydown',function(evt){ // If the key isn't excempt AND the text is longer than length stop the action. if(excempt.indexOf(evt.which) === -1 && $elem.text().length > length) { evt.preventDefault(); return false; } }); } }); }); 
 div { background-color:#eee; border: 1px solid black; margin:5px; width:300px; height:100px; } 
 <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script> <div contenteditable="true" data-input-length="100"> You can type a 100 characters here </div> <div contenteditable="true" data-input-length="150"> You can type a 150 characters here </div> <div contenteditable="true" data-input-length="10"> You can type a 10 characters here </div> 
 $("[contenteditable=true]").keydown(function(e) { var max = $(this).attr("maxlength"); if (e.which != 8 && $(this).text().length > max) { e.preventDefault(); } }); 

这是最好的方式来做这个最普遍的forms,只为我工作!

 <div contenteditable="true" name="choice1" class="textfield" max="255"></div> 
  $('.textfield').on("keypress paste", function (e) { if (this.innerHTML.length >= this.getAttribute("max")) { e.preventDefault(); return false; } }); 
 var onKeyPress = function () { var keyCode = window.event.keyCode, isNumeric = (keyCode > 47 && keyCode < 58), isNotEnterKey = !!(window.event.keyCode !== 13); (isNotEnterKey) || (this.blur()); return (isNumeric && this.innerText.length < 3); }; 

@ user113716的答案的一个更广义的修订,它不适用于多个contenteditable字段(它计算所有与给定id匹配的元素的字符总数 ,因此您只能在页面上input最大字符总数 )。

此解决scheme允许您使用常规类,并独立限制每个可满足字段中的字符数。

html:

 <div contenteditable="true" name="choice1" class="textfield"></div> 

而JavaScript:

 MAX_TEXTINPUT = 10; TEXTFIELD_CLASS = "textfield" $(document).ready(function() { //binding keyup/down events on the contenteditable div $('.'+TEXTFIELD_CLASS).keydown(function(e){ check_charcount(TEXTFIELD_CLASS, MAX_TEXTINPUT, e); }); }) function check_charcount(inputclass, max, e) { var focused = $(document.activeElement) if(focused.hasClass(inputclass) && e.which != 8 && $(focused).text().length >= max) { e.preventDefault(); } } 

如果你想使它与class级工作。 换句话说,元素将能够共享类名,并且还有自己独特的计数:

 var content_id = '.myclass'; max = 1; //binding keyup/down events on the contenteditable div $(content_id).keyup(function(e){ check_charcount(this, max, e); }); $(content_id).keydown(function(e){ check_charcount(this, max, e); }); function check_charcount(elem, max, e){ if(e.which != 8 && $(elem).text().length >= max){ e.preventDefault(); } }