问题
在实例列表页面,点击详情按钮,在关上弹窗后,大拇指习惯性的点了下空格键,发现怎么又弹窗了?
尽管从界面看不错来,但从 devTool 的 Elements 中是能够看到,有两个 dialog 弹窗元素。
剖析
因为这个页面不是我负责,一开始认为是在 click 的时候,加上 stop 等修饰符就能够。
原来是上面这样的:
<el-button type="text" @click="showDetail(scope.row)"> 详情 </el-button>
但加了 stop 等修饰符,还是不行。看来事件并不是我想的那么简略。
因为用了 element ui 的 button,所以想着看下文档,会不会有没留神到的阐明。
一眼看完,没有特地的相干阐明。
而后回到页面持续测试,发现关上弹窗后,点击空格键,发现“详情”的字如同闪了一下。
多测试几次,发现问题了。
原来关上弹窗后,button 没有失焦,所以这时候点击空格键,就会再次触发 button 的 click 事件,从而再次关上弹窗。
阐明一下,这里再次关上弹窗,是因为代码没判断是否已关上弹窗的逻辑。这个能够先疏忽。毕竟这里探讨的是失焦问题。
解决方案
使元素失焦,个别是通过 blur 事件。
// 原来
<el-button type="text" @click="showDetail(scope.row)"> 详情 </el-button>
showDetail(rowData) {this.openDialog(rowData)
}
// 革新后
<el-button type="text" @click="showDetail(scope.row, $event)"> 详情 </el-button>
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 事件。
<el-dialog
:visible="visible"
:title="extend.title"
width="880px"
@close="close"
ref="dialog"
tabindex="-1"
>
mounted() {this.$refs.dialog.$el.focus()
}
// mounted 的时候间接执行 focus,有时候会存在时间差问题。所以倡议通过 setTimeout 来设置
mounted() {setTimeout(() => {this.$refs.dialog.$el.focus()
}, 100)
}
可是,这跟计划 1 不是一样吗?也要写那么多代码。。。
这个就要各位衡量取舍了。
最初
- 公众号《毛毛虫的小小蜡笔》
有疑难和问题,请留言。
如果感觉文章还能够,请点赞或珍藏,谢谢。