Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

input 事件与汉字输入法:使用compositionend事件解决 #8

Open
bmxklYzj opened this issue Oct 10, 2017 · 3 comments
Open
Labels

Comments

@bmxklYzj
Copy link
Owner

bmxklYzj commented Oct 10, 2017

input 事件与汉字输入法:使用compositionend事件解决

在使用<input type="text">的input事件的时候 会遇到中文输入法的“bug”,比如:

依次输入“喜茶”触发的事件中 data的值很诡异,只有当最终点击了空格之后 才是我们期望的值。这种情况下就需要借助 compositonstart compositonend 这两个事件。

按下的按键 出现的结果
x 1、2
i 3
c 4
h 5
a 6
空格 7、8

code:

<input type="text" class="input">

function checkLength(val) {
    return val.length > 3;
}

let input = document.querySelector('input');
input.addEventListener('input', function (event) {
    console.log('input', checkLength(event.target.value), event);
});
input.addEventListener('compositionstart', function (event) {
    console.log('compositionstart', checkLength(event.target.value), event);
});
input.addEventListener('compositionend', function (event) {
    console.log('compositionend', checkLength(event.target.value), event);
});

逻辑为:验证输入框中输入的字符数是否 >3 个,可以看到虽然汉字“喜茶”没有超过,但是在输入汉字的过程中是不符合条件的。那么我们要做的是在输入汉字的过程中不触发input,而在按空格键的时候才做校验。

还要注意到上图中input事件总是先于compositionend,如果要在input事件中做一些操作,那么在 compositionend中也要重复调用一下。

function checkLength(val) {
    return val.length > 3;
}
let inputLock = false;
let input = document.querySelector('input');
input.addEventListener('input', function (event) {
    if (inputLock) {
        return;
    }
    // 在输入汉字的情况下这一句不会执行,因为input事件总是先于compositionend
    console.log('input', checkLength(event.target.value), event);
    // doSomething();
});
input.addEventListener('compositionstart', function (event) {
    inputLock = true;
    console.log('compositionstart', checkLength(event.target.value), event);
});
input.addEventListener('compositionend', function (event) {
    inputLock = false;
    console.log('compositionend', checkLength(event.target.value), event);
    // doSomething(); // 如果要在input事件中做一些操作,那么在 compositionend中也要重复调用一下
});

reference
element fe

@bmxklYzj bmxklYzj added the html label Oct 10, 2017
@msz2017
Copy link

msz2017 commented Nov 16, 2017

移动端支持compositionstart、compositionend吗

@bmxklYzj
Copy link
Owner Author

@msz2017 android支持,ios safari mobile不支持 mdn reference

@bmxklYzj
Copy link
Owner Author

目前chrome会先触发compositionend再触发input,所以只需要:

// 伪代码
if (compositionstart) {
    lock = true
}
if (compositionend) {
    lock = false
}
if (input) {
    if (lock) {
        return;
    }
   // do something
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

2 participants