问题
在实例列表页面,点击详情按钮,在打开弹窗后,大拇指习惯性的点了下空格键,发现怎么又弹窗了?
虽然从界面看不错来,但从devTool的Elements中是可以看到,有两个dialog弹窗元素。
分析
因为这个页面不是我负责,一开始以为是在click的时候,加上stop等修饰符就可以。
原来是下面这样的:
详情
但加了stop等修饰符,还是不行。看来事情并不是我想的那么简单。
因为用了element ui的button,所以想着看下文档,会不会有没注意到的说明。
一眼看完,没有特别的相关说明。
然后回到页面继续测试,发现打开弹窗后,点击空格键,发现“详情”的字好像闪了一下。
多测试几次,发现问题了。
原来打开弹窗后,button没有失焦,所以这时候点击空格键,就会再次触发button的click事件,从而再次打开弹窗。
说明一下,这里再次打开弹窗,是因为代码没判断是否已打开弹窗的逻辑。这个可以先忽略。毕竟这里探讨的是失焦问题。
解决方案
使元素失焦,一般是通过blur事件。
// 原来
详情
showDetail(rowData) {
this.openDialog(rowData)
}
// 改造后
详情
showDetail(rowData, event) {
// 这里需要注意下,点击的target可能不是button,因为el-button最终生成的是button和span元素,所以需要判断下
if (event.target.nodeName === 'SPAN') {
event.target.parentNode.blur()
} else {
event.target.blur()
}
this.openDialog(rowData)
}
上面的方法是能解决,但貌似有个问题:要每个地方都要加事件注入和失焦的判断逻辑。
那能否更好的解决?
很明显,如果弹窗中有input等可输入的标签,是可以让input自动聚焦,从而使button失焦来解决问题。
但如果弹窗中的内容只是展示的呢?比如弹窗中没有input等标签,都是div呢?
这就要用到tabindex属性了。
tabindex=负值 (通常是tabindex=“-1”),表示当前元素是可以聚焦的,但不能通过键盘来导航访问。
所以在el-dialog中设置tabindex属性,以及mounted的时候,触发focus事件。
mounted() {
this.$refs.dialog.$el.focus()
}
// mounted的时候直接执行focus,有时候会存在时间差问题。所以建议通过setTimeout来设置
mounted() {
setTimeout(() => {
this.$refs.dialog.$el.focus()
}, 100)
}
可是,这跟方案1不是一样吗?也要写那么多代码。。。
这个就要各位权衡取舍了。
最后
- 公众号《毛毛虫的小小蜡笔》
有疑问和问题,请留言。
如果觉得文章还可以,请点赞或收藏,谢谢。