在 web 开发中,我们通常需要对输入的内容进行校验。这段代码虽然执行起来没有什么问题,但是会产生非直接输入,比方说我们输入“树莓派”,中间过程会输入拼音,每次输入字母都会触发input事件,然而当中文输入完成之前,都属于非直接输入。

未禁止非直接输入


可以看到,当我们输入 “树莓派” 时,触发了9次 input 事件,这并非是我们想要的结果,我们希望直接输入(中文输入完成)后,再触发 input 的业务逻辑,此时就需要引入其他两个事件 compositionstart 和 compositionend

事件解释

  • compositionstart
    是指中文输入法开始输入触发,每次输入开始仅执行一次,执行的开始是 end 事件结束了才会触发

  • compositonupdate
    是指中文输入法在输入时触发,也就是可能得到 shu’mei 这种内容,这里返回的内容是实时的,仅在 start 事件触发后触发,输入时实时触发

  • compositionend
    是指中文输入法输入完成时触发,这是得到的结果就是最终输入完成的结果,此事件仅执行一次。
    需要特别注意的是:该事件触发顺序在 input 事件之后,故而需要在此事件的处理逻辑里调用一次 input 里边的业务逻辑

禁止非直接输入

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
// 添加标记位 lock ,当用户未输入完时,lock 为 true
var lock = false;
var inputEle = document.getElementById('inputEle');
// input 事件中的处理逻辑, 这里仅仅打印文本
var todo = function (text) {
console.log(text)
};
inputEle.addEventListener('compositionstart', function () {
lock = true;
});
inputEle.addEventListener('compositionend', function (event) {
lock = false;
// compositionend 事件发生在 input 之后,故此需要此处调用 input 中逻辑
todo(event.target.value);
});
inputEle.addEventListener('input', function (event) {
// 忽略一切非直接输入,不做逻辑处理
if (!lock) todo(event.target.value);
});


可以看到,此时已经过滤了全部非直接输入,只有当用户输入中文结束时才会触发 input 中的业务逻辑 ~