主页 > 前端 > javascript >
来源:未知 时间:2023-03-23 09:31 作者:小飞侠 阅读:次
[导读] js中中文输入判断compositionstart和compositionend事件 需求 最近有个需求,根据input输入的文字进行列表过滤。这是个很常见的需求。于是大致的代码如下: templatedivid=appinputtype=text:value=fil...
js中中文输入判断compositionstart和compositionend事件 需求 最近有个需求,根据input输入的文字进行列表过滤。这是个很常见的需求。于是大致的代码如下: <template> <div id="app"> <input type="text" :value="filterText" @input="onInput" /> <ul> <li v-for="item in filteredList" :key="item"> {{ item }} </li> </ul> </div> </template> <script> export default { name: "app", data() { return { filterText: "", list: [ "爱与希望", "花海", "Mojito", "最长的电影", "爷爷泡的茶" ] }; }, computed: { filteredList() { if (!this.filterText) { return this.list; } return this.list.filter(item => item.indexOf(this.filterText) > -1); } }, methods: { onInput(e) { this.filterText = e.target.value; } } }; </script> 在输入框中监听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事件中的筛选操作。 代码变成如下: <template> <div id="app"> <input type="text" :value="filterText" @input="onInput" @compositionstart="onCompositionStart" @compositionend="onCompositionEnd" /> <ul> <li v-for="item in filteredList" :key="item"> {{ item }} </li> </ul> </div> </template> <script> export default { name: "app", data() { return { filterText: "", list: [ "爱与希望", "花海", "Mojito", "最长的电影", "爷爷泡的茶" ], lock; false, // 打标 }; }, computed: { filteredList() { if (!this.filterText) { return this.list; } return this.list.filter(item => item.indexOf(this.filterText) > -1); } }, methods: { onInput(e) { if (!this.lock) { this.filterText = e.target.value; } }, onCompositionStart() { this.lock = true; }, onCompositionEnd(e) { this.filterText = e.data; this.lock = false; } } }; </script> 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网。 |
自学PHP网专注网站建设学习,PHP程序学习,平面设计学习,以及操作系统学习
京ICP备14009008号-1@版权所有www.zixuephp.com
网站声明:本站所有视频,教程都由网友上传,站长收集和分享给大家学习使用,如由牵扯版权问题请联系站长邮箱904561283@qq.com