问题
登录页面,输入验证码的时候,自己在代码里加了对Enter键的监听,导致与输入法冲突。具体现象是:验证码是英文的,用中文输入法输入,在有候选字的情况下按Enter,这时先触发登录,没有先转化为code。
如图
资料
经过查找compositionstart
和compositionend
这两个方法刚好满足需求。
简单的说一下这两个方法的属性。
compositionstart
MDN文档地址: https://developer.mozilla.org/zh-CN/docs/Web/Events/compositionstart
解释:
文本合成系统如input method editor
(即输入法编辑器)开始新的输入合成时会触发compositionstart
事件。
MDN文档地址: https://developer.mozilla.org/zh-CN/docs/Web/Events/compositionend
解释:
当文本段落的组成完成或取消时, compositionend 事件将被触发 (具有特殊字符的触发, 需要一系列键和其他输入, 如语音识别或移动中的字词建议)。
看了下vue的源码,也是通过这种方式来解决输入法按键冲突的问题。
https://github.com/vuejs/vue/blob/dev/dist/vue.js#L8482
实现
- jQuery实现
const $input = $('#ipt');
let composing = false;
$input
.on('compositionstart', () => {
composing = true;
})
.on('compositionend', () => {
composing = false;
})
.on('keyup', () => {
if (!composing) {
// do something ...
}
})
-
vue的demo
<!DOCTYPE html> <html> <head> <title>Enter键与输入法候选词</title> <script src="https://unpkg.com/vue"></script> </head> <body> <div id="app"> <h2>Enter键与输入法候选词</h2> <section> <input type="checkbox" v-model="judgeComposing">开启composing判断 </section> <section> <div> <form> <div> <label for="username ">用户名</label> <input ref="username " type="text " id="username " laceholder="输入用户名 "> </div> <div> <label for="code ">用中文输入法输入zhongwen</label> <input ref="code " type="text " id="code " laceholder="输入zhongwen "> </div> <button @click="loginAction ">登录</button> </form> </div> </section> <section> <div style="margin-top: 20px; ">{{log}}</div> </section> </div> <script> var app = new Vue({ el: '#app', data: { message: 'Hello Vue!', log: '', judgeComposing: true }, watch: { judgeComposing: (value) => { app.log += ("是否开启composing:" + value) } }, mounted() { this.log += "Mounted finished. \n " document.onkeydown = (e) => { e = window.event || e if (e.code === 'Enter' || e.code === 'NumpadEnter') { // 验证在登录界面和按得键是回车键enter this.log += "按下了Enter。 \n " if (this.judgeComposing) { const someOneIsComposing = [this.$refs.username, this.$refs.code].reduce((composing, component) => { return composing || component.isComposing }, false) if (someOneIsComposing === false) { this.loginAction() } } else { this.loginAction() } } } }, methods: { loginAction() { alert("loginAction ") } }, }) </script> </body> <style> </style> </html>