前端开发

 首页 > 前端开发 > javascript > js中中文输入判断compositionstart和compositionend事件最新评论添加评论

js中中文输入判断compositionstart和compositionend事件最新评论添加评论

分享到:
【字体:
导读:
         [导读] js中中文输入判断compositionstart和compositionend事件 需求 最近有个需求,根据input输入的文字进行列表过滤。这是个很常见的需求。于是大致的代码如下: templatedivid=appinputtype=text:value=fil...

js中中文输入判断compositionstart和compositionend事件

需求

最近有个需求,根据input输入的文字进行列表过滤。这是个很常见的需求。于是大致的代码如下:



在输入框中监听input事件,然后触发filteredList列表的改变。


一切都是那么自然。


然而当我们输入中文的时候,由于拼音会先显示,导致在输入中文的过程中,触发筛选的列表空的,最后中文显示出来的时候,才会有显示结果。


compositionstart和compositionend

于是在网上搜索有这么两个事件, compositionstart和 compositionend


MDN: https://developer.mozilla.org/zh-CN/docs/Web/Events/compositionstart


当用户使用拼音输入法开始输入汉字时,compositionstart事件就会被触发。当文本段落的组成完成或取消时, compositionend 事件将被触发。


也就是说,在我们开始输入中文的时候会触发一次compositionstart事件,中文输入过程中不会再出发compositionstart事件,最后输入中文完成触发compositionend 事件。


而且经过试验发现,在输入中文的时候,compositionstart先于input事件触发。


有了这个前提那这就好办了,我只需打个标 lock,当compositionstart触发时, lock=true,当compositionend触发时, lock=false。只有在lock为false的时候,才执行input事件中的筛选操作。


代码变成如下:



v-model形式

上面的代码我们使用的不是vue的 v-model双向绑定的形式,如果你使用 v-model的形式,你会发现在输入中文的过程中不会触发input事件。


查看vue的源码 src/platforms/web/runtime/directives/model.js,有这么几行代码:


export default {
  inserted (el, binding, vnode) {
    if (vnode.tag === 'select') {
      setSelected(el, binding, vnode.context)
      el._vOptions = [].map.call(el.options, getValue)
    } else if (vnode.tag === 'textarea' || isTextInputType(el.type)) {
      el._vModifiers = binding.modifiers
      if (!binding.modifiers.lazy) {
        // Safari < 10.2 & UIWebView doesn't fire compositionend when
        // switching focus before confirming composition choice
        // this also fixes the issue where some browsers e.g. iOS Chrome
        // fires "change" instead of "input" on autocomplete.
        el.addEventListener('change', onCompositionEnd)
        if (!isAndroid) {
          el.addEventListener('compositionstart', onCompositionStart)
          el.addEventListener('compositionend', onCompositionEnd)
        }
        /* istanbul ignore if */
        if (isIE9) {
          el.vmodel = true
        }
      }
    }
  }
}
//...
function onCompositionStart (e) {
  e.target.composing = true
}
function onCompositionEnd (e) {
  // prevent triggering an input event for no reason
  if (!e.target.composing) return
  e.target.composing = false
  trigger(e.target, 'input')
}
function trigger (el, type) {
  const e = document.createEvent('HTMLEvents')
  e.initEvent(type, true, true)
  el.dispatchEvent(e)
}

可以发现,原来vue早已做了相同的操作,所以v-model帮我们做了很多优化处理,这也是vue如此优秀的原因之一。

以上就是js中中文输入判断compositionstart和compositionend事件全部内容,感谢大家支持自学php网。

分享到:
js解析xmind文件代码思路最新评论添加评...
首先,你需要了解Xmind文件的结构和格式。Xmind是一个流行的思维导图工具,其文件格式是一种基于XML的文本格式。你需要了解XML的基本语法和结构。 接下来,你需要选择一种适合你的JavaScript库或工具来解析XML。这里推荐两个常用的库:xml2js和xmldom。xml2js基于回调函数,易于使用,但支持的功能相对较少,如果需要更强...
模拟vue数据劫持实现发布订阅核心代码最...
模拟vue数据劫持实现发布订阅核心代码 // 定义一个依赖收集器 class Dep {   constructor() {     this.subs = [] // 订阅者列表   }   // 添加订阅者   addSub(sub) {     this.subs.push(sub)   }   // 通知所有订阅者数据已更新   notify() {     this.subs.forEach(s...
  •         php迷,一个php技术的分享社区,专属您自己的技术摘抄本、收藏夹。
  • 在这里……