在项目中,我们有一个这样的需求——实时监测用户输入内容的长度并做限制。但是在开发这个功能时,会碰到一些问题。怎么解决这些问题呢?需要用到两个陌生的事件:compositionstart事件和compositionend事件。
举个例子:实时监测用户输入内容的长度,最大长度为10个字符,超出后不再允许用户输入。
和大部分人的想法一样,通过input事件实时检测用户输入的内容长度,并做判断。如果超出最大长度,则截取前10个字符。
代码如下:
您还能输入10个字符
// 获取DOM元素
var msg = document.getElementById('msg');
var num = document.getElementById('num');
msg.oninput = function () {
}
};
但是这样实现有一些问题。
1:当用户输入中文的过程中,会实时计算中文拼音的长度。但这不是我们想要的效果,我们想要的是,当用户输入中文完毕以后,再去计算用户输入的内容长度。
2:在safari浏览器下,当用户一次性输入的中文拼音大于最大长度时,则不能正常运行。
解决这些问题需要用到开头提到的compositionstart事件和compositionend事件。MDN网站上有关于这两个事件的介绍,简单的描述一下:
compositionstart:在输入中文或语音等需要等待一连串的输入操作之前触发执行。
compositionend:在输入中文或语音结束或者取消后触发执行。
改进一下我们的解决方案,使用一个变量标识当前用户输入的是否为中文,然后在input事件中根据这个变量的值决定是否实时计算内容的长度。JS代码如下:
var msg = document.getElementById('msg');
var num = document.getElementById('num');
var check = function () {
}
}.bind(msg);
// 该变量标识用户当前输入是否为中文
var isInputChinese = false;
msg.oninput = function () {
// 如果变量为false,说明用户输入的是普通单字符,则执行check方法
!isInputChinese && check();
};
msg.addEventListener('compositionstart', function() {
// 该事件执行,说明用户开始输入中文,将变量设置为true
isInputChinese = true;
});
msg.addEventListener('compositionend', function() {
// 该事件执行,说明用户输入中文完毕,将变量设置为false,并执行check方法检测
isInputChinese = false;
check();
});
注意,当输入中文时,这三个事件的执行顺序为compositionstart、input、compositionend。
-------------------封装 -------------------
如果一个页面中有多个地方需要这样的功能,我们可以使用面向对象的方法将其封装,供多次使用。具体封装代码如下:
您还能输入20个字符
您还能输入30个字符
您还能输入10个字符
// 封装限制输入框字符数量功能
(function () {
var LimitCharNum = function (inputArea, numArea, maxLength) {
this.inputArea = inputArea;
this.numArea = numArea;
this.maxLength = maxLength;
this.isInputChinese = false;
// 初始化
this.init();
}
LimitCharNum.prototype = {
constructor: LimitCharNum,
init: function() {
// 绑定输入事件
this.inputArea.addEventListener('input', function () {
!this.isInputChinese && this.check();
}.bind(this));
this.inputArea.addEventListener('compositionstart', function () {
this.isInputChinese = true;
}.bind(this));
this.inputArea.addEventListener('compositionend', function () {
this.isInputChinese = false;
this.check();
}.bind(this));
},
check: function () {
}
}
};
// 注册构造函数
window.LimitCharNum = LimitCharNum;
})();
// 开始使用
function $(id) {
return document.getElementById(id);
}
new LimitCharNum($('msg0'), $('num0'), 20);
new LimitCharNum($('msg1'), $('num1'), 30);
new LimitCharNum($('msg2'), $('num2'), 10);
上面使用的是ES5的语法,大家可以尝试一下使用ES6的语法封装。
文章到此结束,如果大家有什么更好的解决方案欢迎在评论中提出(不知道能不能评论~~~)。
马上过年了,祝大家新年快乐合家欢!!
领取专属 10元无门槛券
私享最新 技术干货