产品要求,输入框中不能输入特殊字符和表情,但是正向思维的话,输入可能不太好控制,所以就逆向思维,只能输入数字字母和中文
<input id="memo" class="common-input" name="memo" onKeyUp="ValidateValue(this)" maxlength="300"/>
function ValidateValue(textbox) {
var regx = /^[\u4E00-\u9FA5A-Za-z0-9]+$/
var textboxvalue = textbox.value;
var index = textboxvalue.length - 1;
if(!regx.test(textboxvalue)) {
var s = textboxvalue.substring(0, index);
textbox.value = s;
}
}
代码如上。本来以为稳妥的,没啥问题,然后自测的时候发现,会出现意料以外的情况如图
然后就有点不知所措,后百度得到
在输入中文(包括语音识别时)会先后触发compositionstart、compositionend事件,类似于keydown和keyup的组合。
触发compositionstart时,文本框会填入 “虚拟文本”(待确认文本),同时触发input事件;在触发compositionend时,就是填入实际内容后(已确认文本)
compositionstart 事件触发于一段文字的输入之前(类似于 keydown 事件,但是该事件仅在若干可见字符的输入之前,而这些可见字符的输入可能需要一连串的键盘操作、语音识别或者点击输入法的备选词)。
compositionend 当文本段落的组织已经完成或取消时,会触发该事件。
因此得到想法:声明一个标记flag,在compositionstart、compositionend两个事件过程之间的时候flag值为false,在input事件中通过flag的值来判断当前输入的状态。
更改后的代码
var flag = true;
$('.common-input').on('compositionstart',function(){
flag = false;
})
$('.common-input').on('compositionend',function(){
flag = true;
})
function ValidateValue(textbox) {
setTimeout(function(){
if (flag) {
var regx = /^[\u4E00-\u9FA5A-Za-z0-9]+$/
var textboxvalue = textbox.value;
var index = textboxvalue.length - 1;
if(!regx.test(textboxvalue)) {
var s = textboxvalue.substring(0, index);
textbox.value = s;
}
}
}, 100)
}