说在前面
🎈input输入框大家应该都很熟悉了吧,不知道大家有没有遇到过这样的一种情况:如上图,在中文输入过程中,输入的拼音也会触发input框的input事件,有些时候我们并不希望在中文输入的过程中拼音触发input事件。
在日常开发中,输入框是一个常见的组件,但是在拼音输入过程中,每次输入都会触发input事件,这可能会导致不必要的操作。本文将介绍一种解决该问题的Vue指令,使得在拼音输入过程中不会触发input事件,从而优化输入框体验。
效果展示
实现原理
1、compositionstart和compositionend事件
我们需要了解compositionstart和compositionend两个事件。当用户开始输入拼音时,会触发compositionstart事件,此时输入框的值并没有真正改变。随着输入的进行,最终会触发compositionend事件,此时输入框的值才会真正改变。我们可以通过监听这两个事件,来控制何时触发input事件。
具体实现方式是,在监听到compositionstart事件时,将输入框的值存储下来,然后在监听到compositionend事件时,再将输入框的值与之前存储的值进行比较,如果不同,则触发自定义的input事件,并将新值作为参数传递给监听器。
2、代码实现
(1)输入框
<div class="input-text-title">正常情况</div> <div class="input-text-content">{{ inputText }}</div> <input placeholder="请输入" class="input-text" @input="doInput" id="inputContent" />
简单定义一个输入框,监听其input事件,inputText保存实时输入内容并展示到页面上。
(2)监听compositionstart和compositionend事件
const inputContent = document.getElementById("inputContent"); inputContent.addEventListener("compositionstart", () => { this.isComposing = true; this.inputComplate(inputContent.value); }); inputContent.addEventListener("compositionend", () => { this.isComposing = false; if (inputContent.value !== this.inputText) { this.inputComplate(inputContent.value); } });
首先,我们通过getElementById方法获取到id为"inputContent"的输入框元素,并将其赋值给inputContent常量。
然后,我们给inputContent元素添加compositionstart事件的监听器。在事件触发时,会执行回调函数。在回调函数中,我们将isComposing变量设置为true,表示正在进行拼音输入,然后调用inputComplate方法处理输入框的值,并将输入框的值作为参数传递给inputComplate方法。
接下来,我们给inputContent元素添加compositionend事件的监听器。在事件触发时,同样会执行回调函数。在回调函数中,我们将isComposing变量设置为false,表示拼音输入结束,然后同样调用inputComplate方法处理输入框的值,并将输入框的值作为参数传递给inputComplate方法。
通过监听这两个事件,并在事件触发时调用相应的处理方法,我们可以实现在拼音输入过程中控制input事件的触发时机,从而达到不触发input事件的效果。
(3)input事件判断是否正在输入拼音
inputComplate(value) { this.inputText = value; }, doInput(event) { if (this.isComposing) return; const value = event.target.value; this.inputComplate(value); },
输入框input事件绑定的是doInput
方法,这个方法在这里只是用于过渡一下,在这里我们需要判断当前是否正在输入拼音,如果是在输入拼音的话我们就直接返回,不进行后续操作,如果不是的话则调用inputComplate
进行后续处理,真正的处理逻辑应该是在inputComplate
方法中。
这样我们就简单的完成了一个忽略拼音输入过程中的input事件
的功能
本文到此结束
且慢,虽然上面这样操作之后可以得到一个可以忽略拼音输入过程中的input事件的输入框;但是,如果我们有很多个输入框需要加上这个功能呢?这样的话我们每写一个input框,想要加上这个功能的话不还得加一堆乱七八糟的代码来处理,这明显很不合理。
(4)封装成一个vue指令
export default { bind(el, binding) { let isComposing = false; let value = ""; el.addEventListener("compositionstart", () => { isComposing = true; value = el.value; }); el.addEventListener("compositionend", () => { isComposing = false; if (value !== el.value) { binding.value(el.value); } }); // 添加自定义的input事件监听器 el.addEventListener("input", (event) => { if (isComposing) { return; } const value = event.target.value; // 处理输入框的值 binding.value(value); }); }, };
<input placeholder="输入试试" class="input-text" v-JIgnorePinyin="doInput1" />
在bind钩子函数中,我们首先定义了两个变量isComposing和value,分别用于记录是否正在进行拼音输入和输入框的值。
然后,我们给输入框元素el添加compositionstart事件的监听器。在事件触发时,将isComposing设置为true,表示正在进行拼音输入,并将输入框的值赋给value。
接下来,我们给输入框元素el添加compositionend事件的监听器。在事件触发时,将isComposing设置为false,表示拼音输入结束。然后,我们比较value和输入框的当前值el.value是否相等,如果不相等,则说明输入框的值已经发生了变化,此时我们调用binding.value方法,将当前输入框的值el.value作为参数传递给绑定该指令的处理函数。
最后,我们给输入框元素el添加input事件的监听器。在事件触发时,首先判断isComposing的值,如果为true,则直接返回,不做任何处理。如果isComposing的值为false,说明拼音输入已经完成,此时我们获取输入框的值event.target.value,并将其作为参数调用binding.value方法,从而处理输入框的值。
通过定义这个自定义指令,我们可以在Vue组件中使用它来监听拼音输入过程中的事件,并执行相应的处理逻辑,从而实现更加灵活的输入框交互。
这样的话后面需要加功能只需要一个指令即可搞定。
组件库
组件文档
目前该组件也已经收录到我的组件库,组件文档地址如下:
http://jyeontu.xyz/jvuewheel/#/JMouseMenu
组件内容
组件库中还有许多好玩有趣的组件,如:
- 悬浮按钮
- 评论组件
- 词云
- 瀑布流照片容器
- 视频动态封面
- 3D轮播图
- web桌宠
- 贡献度面板
- 拖拽上传
- 自动补全输入框
- 图片滑块验证
等等……
组件库源码
组件库已开源到gitee,有兴趣的也可以到这里看看:https://gitee.com/zheng_yongtao/jyeontu-component-warehouse
觉得有帮助的可以点个star~
有什么问题或错误可以指出,欢迎pr~
有什么想要实现的组件或想法可以联系我~
公众号
关注公众号『前端也能这么有趣
』,获取更多有趣内容。
发送『组件库
』获取源码
说在后面
🎉 这里是 JYeontu,现在是一名前端工程师,有空会刷刷算法题,平时喜欢打羽毛球 🏸 ,平时也喜欢写些东西,既为自己记录 📋,也希望可以对大家有那么一丢丢的帮助,写的不好望多多谅解 🙇,写错的地方望指出,定会认真改进 😊,偶尔也会在自己的公众号『
前端也能这么有趣
』发一些比较有趣的文章,有兴趣的也可以关注下。在此谢谢大家的支持,我们下文再见 🙌。