我在我的Web应用程序中使用了contenteditable div元素,我正在尝试提出一个限制区域中允许的字符数量的解决方案,一旦达到限制,尝试输入字符就什么都不做。这是我到目前为止:
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));
}
}
此DOES将字符数限制为“max”指定的数字,但是一旦通过jquery .text()函数设置了区域的文本,光标就会将自身重置为该区域的开头。因此,如果用户继续键入,则新输入的字符将插入文本的开头,并且将删除文本的最后一个字符。所以,我只需要一些方法将光标保持在可信区域文本的末尾。
如果达到最大值,如何将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
应该足够了。
如果你想让它适用于类。换句话说,元素将能够共享类名,并且仍然具有自己的唯一计数:
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();
}
}
@ user113716答案的另一个版本。支持“粘贴”事件,以及一些文本热键,如CTRL + A.
$('#'+content_id).on('keydown paste', function (e) { maxLimitForContenteditableDiv(e, 140) });
function maxLimitForContenteditableDiv(e, limit) {
var allowedKeys = false;
if (e.type === 'keydown') {
allowedKeys = (
e.which === 8 || /* BACKSPACE */
e.which === 35 || /* END */
e.which === 36 || /* HOME */
e.which === 37 || /* LEFT */
e.which === 38 || /* UP */
e.which === 39 || /* RIGHT*/
e.which === 40 || /* DOWN */
e.which === 46 || /* DEL*/
e.ctrlKey === true && e.which === 65 || /* CTRL + A */
e.ctrlKey === true && e.which === 88 || /* CTRL + X */
e.ctrlKey === true && e.which === 67 || /* CTRL + C */
e.ctrlKey === true && e.which === 86 || /* CTRL + V */
e.ctrlKey === true && e.which === 90 /* CTRL + Z */
)
}
if (e.type === 'paste') {
setTimeout(function () {
$(e.target).text($(e.target).text().slice(0, limit));
});
}
if (!allowedKeys && $(e.target).text().length >= limit) {
e.preventDefault();
}
实现这一目标的简单方法:
<div onkeypress="return (this.innerText.length <= 256)" contenteditable="true">
首先,这种事情对用户来说很烦人:我建议改为做类似于StackOverflow的注释字段,它允许你输入任意多或少的内容,向你显示一条消息,告诉你输入了多少个字符以及是否太多或太少,并且拒绝让您提交长度无效的评论。
其次,如果你真的必须限制文本的长度,如果内容太长则在每次击键时替换<div>
的全部内容是不必要的昂贵,并且会使编辑器在较慢的机器上无响应。我建议处理keypress
事件并简单地阻止使用preventDefault()
在事件上插入字符(或者在IE中,将事件的returnValue
设置为true
,假设您正在使用attachEvent
)。这不会阻止用户粘贴文本,因此您需要处理paste
事件(Opera或Firefox <3中不存在,因此您需要某种基于轮询的解决方案) 。由于您无法提前访问正在粘贴的内容,因此您无法知道粘贴是否会超过字符限制,因此您需要设置计时器以便再次检查长度粘贴后。在所有情况下,第一种选择似乎比我更好。
以下解决方案还考虑了控制键(对应于不可打印的字符)。
//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;
}
});
这是做这种最通用的形式的最佳方式,对我来说非常有用!
<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;
}
});
这是我通过jQuery绑定实现它的方式,通过向内容可编辑元素添加属性数据输入长度使我更容易。只需在文档中的任何位置添加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();
}
});
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匹配的所有元素的字符总数,因此您只能在页面上输入最多字符总数)。
此解决方案允许您使用通用类,并独立限制每个contenteditable字段中的字符数。
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();
}
}