美文网首页
# JS 按键监听 与 输入法候选词选择 冲突

# JS 按键监听 与 输入法候选词选择 冲突

作者: ted4kra | 来源:发表于2021-05-26 21:02 被阅读0次

    问题

    登录页面,输入验证码的时候,自己在代码里加了对Enter键的监听,导致与输入法冲突。具体现象是:验证码是英文的,用中文输入法输入,在有候选字的情况下按Enter,这时先触发登录,没有先转化为code。

    如图


    FinalVideo_1622033824.952332.gif

    资料

    经过查找compositionstartcompositionend这两个方法刚好满足需求。
    简单的说一下这两个方法的属性。

    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

    实现

    1. jQuery实现
    
    const $input = $('#ipt');
    let composing = false;
    
    $input
        .on('compositionstart', () => {
            composing = true;
        })
        .on('compositionend', () => {
            composing = false;
        })
        .on('keyup', () => {
            if (!composing) {
                // do something ...
            }
        })
    
    
    1. 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>
      

    相关文章

      网友评论

          本文标题:# JS 按键监听 与 输入法候选词选择 冲突

          本文链接:https://www.haomeiwen.com/subject/bldlsltx.html