要点
button 点击之后处于聚焦状态,当键盘输入 Enter 或 Space 的时候会触发它的 click 事件
起因
当我以为这是最后一个Bug,改完就可以去吃饭时……没想到最后花了半天时间才找到根本原因……
当时正在写 Vue3 的项目,大致的流程是:
- 点击列表某一项的
button,弹出弹窗 - 用户扫码(本地用键盘模拟扫码,
enter键作为结束标志) - 扫码成功之后做一些处理再关闭弹窗
然而经过排查会发现如上图所示,在第 2 步的时候又弹出了弹窗
当时我一脸问号,反复排查了流程中是否有多余的打开弹窗的语句,最后只锁定到了第 1 步的点击
至此我离真相只差一步,只要找到还有什么渠道会触发 click 事件,并且想办法屏蔽掉就 OK 了
そうですね ,按钮点击之后聚焦情况下,键盘输入 Enter 或 Space 会触发 click 事件
解决办法
由MDN已知:点击
<button>会让浏览器和操作系统(默认情况下)将焦点放在其上。<input>的type="button"和type="submit"也是一样的
在聚焦状态,通过键盘 enter 或者 space键可以触发按钮的点击事件,要阻止这种行为思路有两种:
- 点击按钮后让按钮失焦
- 屏蔽按钮上的键盘事件
点击按钮后让按钮失焦
<button onclick="clickBtn"></button>
function clickBtn (e) {
e.target.blur()
}
屏蔽按钮上的键盘事件
- 在 Vue 中屏蔽
<!-- 阻止按钮监听所有键盘事件 -->
<button @keydown.prevent></button>
<!-- 阻止按钮监听键盘 enter 和 space 键按下 -->
<button @keydown.enter.prevent @keydown.space.prevent></button>
- 原始
<button onkeydown="dealKeydown"></button>
// 对于 enter 或 space 键阻止原生行为
function dealKeydown (e) {
if (e.keycode === 13 || e.keyCode === 32) {
e.preventDefault()
}
}