需求
用户要求input框仅能输入数字,不允许失焦时才处理非数字字符。
初次方案: v-modl绑定数据。onkeypress禁止键盘非数字按键,input处理半角全角和非数字字符。
问题
问题1.
日语输入法下,按下数字字符可以组合出非数字字符。
问题2.
日语输入法下,tab键切换/↑↓频繁切换时。会导致input事件处理异常。
例如:input中重复赋值、input框中的值异常清理。
原因:输入法待选文字切换时会频繁触发input事件,并且在框中显示的待选文字,也会在value中出现。
解决方案
compositionstart事件、compositionend事件、input事件
输入法输入时,会先触发compositionstart、compositionupdate、compostionend事件,之后才会触发input事件。但是直接输入数字/字母不会触发compostionstart/compositionupdate/compostitionend事件,只会触发input事件。
//此处是通过当input框focus事件给当前input框添加input相关事件
inputResultCheck(element) {
let inCompositionEvent = false; //是否组合输入flag
let vm = this;
let inputEvent = function () {
//普通input输入会直接触发
if(!inCompositionEvent){
//do something
//vue下通过$nextTick触发单独事件,普通js下通过setTimeout函数触发单独事件。原因是为了调整被触发事件的优先度。防止与compositionend事件冲突
}
};
let inputStratEvent = function () {
//触发组合输入事件,设置flag,禁止触发input事件
inCompositionEvent = true;
};
let inputEndEvent = function () {
//组合输入事件结束,修改falg,触发input事件
inCompositionEvent = false;
//可以针对组合输入做一些单独的操作
};
element.target.removeEventListener('input', inputEvent);
element.target.removeEventListener('compositionstart', inputStratEvent);
element.target.removeEventListener('compositionend', inputEndEvent);
element.target.addEventListener('input', inputEvent);
element.target.addEventListener('compositionstart', inputStratEvent);
element.target.addEventListener('compositionend', inputEndEvent);
}