问题:
最近遇到一个问题,在vue中的按钮点击之后出现弹框,如果此时不做任何鼠标操作,直接回车,会出现不断调用点击事件,也导致不断出发dialog的初始化,特别dialog有些初始化比较大的时候,更容易发现问题。 原因可以查看HTML: The Living Standard
Keyboard events are always targeted at this focused element.
现象:
这个不仅在vue或者element中会出现,原生的也有这个情况,具体原因未深究,有明白的可以评论区科普一下
解决思路:
首先说一下,本文主要讲解在vue中的处理思路。
根据上图,分别讨论:
1.解决问题发生的源头
其实大多数页面是无感的,只有部分页面会因为重复点击引出问题,所以可以直接在部分有问题的页面,禁用enter回车事件:
document.onkeydown = (e) => {
if (e.keyCode === 13) {
return false;
}
};
2.判断事件类型
我们可以在点击事件中拿到event,根据event的type字段来进行处理(点击事件的type是click,回车的type是keydown):
function handle(e) {
if (e.type === 'click') {
// do
}
}
3.主动取消焦点
上面的图可以看到,即然回车的时候是根据是否有焦点,那我直接在点击之后,取消按钮的焦点不就OK了吗,这个也有三个思路:
3.1 焦点被抢走
通过点击事件之后,主动让其他元素获取焦点,来达到按钮失焦的效果
常见的思路是设置一个input(可以设置长宽不可见,或者直接移到屏幕外面),每次点击时来获取焦点即可
3.2 主动失焦
顾名思义,在按钮中主动的调用oblur方法达到失焦的效果:
function handle(e) {
if (e.type === 'click') {
// do
// 这里的targe 可能要判断好,如果button中包裹的还有其他dom,此时的target不是button,所以要转换成button
e.target.blur();
}
}
3.3 优化
上面的写法,觉得有点粗鲁了,所以想用vue的指令来优化一下:
export default function (Vue) {
let Fun = function (el, binding, vnode) {
el.addEventListener('click', function (event) {
el.blur();
});
};
// after-click-blur 简称 abc
Vue.directive('acb', {
componentUpdated: Fun
});
};
// 调用
<el-button
v-acb
@click="test"
>
测试
</el-button>
这里利用了el.addEventListener不会覆盖原方法的特性,只是追加了一个click方法,在点击的时候均会触发,所以每次都正好能够失焦。
总结
好活当赏,求赞
如有误,欢迎指正