在前端,PC或者H5,input输入的是非拉丁语言,有时候会出现各种异常
- 比如在PC端:
如上图所示,文本框不允许输入 ' 之类的特殊字符,当用户在敲击拼音、还未最终输入时就已经触发了校验,提示输入不合法,有点尴尬。通常我们都是监听 input 或者 change 事件来校验用户输入,也就是说在用户输入拼音的过程中就已经触发了相关事件,进而触发校验。
现实中遇到类似问题时,我们一般会认为是输入法处理不当,这种底层的问题不应该由前端来填坑,然后就放弃治疗了。
- 再比如在移动端:
在input中输入中文的时候,在没有选定文字前,输入的每一个拼音字母也会触发input事件,这显然不是我们想要的。也就是说在手机端,中文输入过程中,默认输入框里面会显示相关的英文字母,这个时候会触发input事件,但是这个时候输入并没有结束,所以导致判断时机不正确。
引入两个事件compositionstart和 compositionend。
关于oninput事件
oninput 是 HTML5 的标准事件,对于检测 textarea, input:text, input:password 和 input:search 这几个元素通过用户界面发生的内容变化非常有用,在内容修改后立即被触发,不像 onchange 事件需要失去焦点才触发。 oninput 事件兼容为ie9+, ie下可以onpropertychange事件,不是本节内容。
compositionstart
当浏览器有非直接的文字输入时, compositionstart事件会以同步模式触发。
compositionend
当浏览器是直接的文字输入时, compositionend会以同步模式触发。
看了两个事件就明白,开始中文输入时会触发compositionstart事件选词结束后会触发compositionend事件,忽略这两个事件之间的input事件即可,为元素添加这个两个事件。
举个例子:
$(function () {
var cpLock = true;
$('#textbox').off().on({
compositionstart: function () {//中文输入开始
cpLock = false;
},
compositionend: function () {//中文输入结束
cpLock = true;
},
input: function () {//input框中的值发生变化
if (cpLock)
this.value = this.value.replace(/[^A-Za-z0-9]/g, '');
}
})
});
添加一个 inputLock 变量,当用户未完成直接输入前,inputLock 为 true,不触发 input 事件中的逻辑,当用户完成有效输入之后,inputLock 设置为 false,触发 input 事件的逻辑。这里需要注意的一点是,compositionend 事件是在 input 事件后触发的,所以在 compositionend事件触发时,也要调用 input 事件处理逻辑。