编程崽

登录

一叶在编程苦海沉沦的扁舟之上,我是那只激情自射的崽

拼音输入中文汉字的事件监听

拼音输入中文汉字的事件监听

前端开发时,很多场景需要监听input输入,当值发生变化,需要进行调用接口、对值进行校验、实时过滤内容等操作。

问题

但当我们使用拼音输入法输入汉语时,可能会遇到一些问题,每次输入拼音的一个字母,都会触发input方法,但得到的内容是正在进行组合的拼音,此时得到的是无效的值,比如如下代码:

html 复制代码
<input id="inputDom" />

<script>
  const inputDom = document.querySelector('#inputDom')
  inputDom.addEventListener('input', (e) => {
    console.log('input触发', e.target.value)
  })
</script>

我们用英文输入hello,然后切换为中文输入法,再输入你好两个字,得到的打印如下:

text 复制代码
input触发 h
input触发 he
input触发 hel
input触发 hell
input触发 hello
input触发 hellon
input触发 helloni
input触发 helloni'h
input触发 helloni'ha
input触发 helloni'hao
input触发 hello你好

就很不对!

新事件监听来解决

这时就需要使用input框的另两个事件,compositionstartcompositionend

当开始输入拼音时,会触发compositionstart事件,拼音输入完成,会触发compositionend,见如下代码:

html 复制代码
<input id="inputDom" />

<script>
  const inputDom = document.querySelector('#inputDom')
  let isCompositioning = false
  inputDom.addEventListener('input', (e) => {
    console.log(`input触发${isCompositioning ? '(组合中)' : ''}`, e.target.value)
  })
  inputDom.addEventListener('compositionstart', (e) => {
    console.log('开始组合')
    // 标记正在组合中
    isCompositioning = true
  })
  inputDom.addEventListener('compositionend', (e) => {
    // 标记组合结束
    isCompositioning = false
    console.log('组合结束', e.target.value)
  })
</script>

同样再输入hello你好,得到的打印:

text 复制代码
input触发 h
input触发 he
input触发 hel
input触发 hell
input触发 hello
开始组合
input触发(组合中) hellon
input触发(组合中) helloni
input触发(组合中) helloni'h
input触发(组合中) helloni'ha
input触发(组合中) helloni'hao
input触发(组合中) hello你好
组合结束 hello你好

最终方案

所以,我们可以通过inputcompositionstartcompositionend三个时间配合,得到我们想要的输入监听结果。

html 复制代码
<input id="inputDom" />

<script>
  const inputDom = document.querySelector('#inputDom')
  let isCompositioning = false
  inputDom.addEventListener('input', (e) => {
    if (isCompositioning) return
    inputChange(e.target.value)
  })
  inputDom.addEventListener('compositionstart', (e) => {
    // 标记正在组合中
    isCompositioning = true
  })
  inputDom.addEventListener('compositionend', (e) => {
    // 标记组合结束
    isCompositioning = false
    // 触发一次修改事件
    inputChange(e.target.value)
  })

  function inputChange(value) {
    console.log(value)
  }
</script>