首先,我们要知道div标签 本身没有没有聚焦状态
通过使用tabIndex属性可以使本身没有聚焦状态的div拥有聚焦
Vue中可以使用this.$refs['xxx'].focus() 聚焦
属性outline可以控制选中的效果,通过 outline='0' 后者 在css样式上加上outline:none 取消聚焦样式
代码如下:
<div ref="selectBox" tabindex="0" class="selected-box" @blur="handleBlur">
CSS:
.selected-box {
outline: none;
}
@blur方法为失去焦点时触发,且会优先于其他点击事件。
最近遇到一个需求,需要点击一个div显示一个列表。
代码如下:
<div>
<div @click="getList" style="background-color: yellow;width: 100px;height: 100px"></div>
<div ref="selectBox" tabindex="0" class="selected-box" :class="{'check':!isBlur}" @blur="handleBlur">
<ul>
<li>hello</li>
<li>hello2</li>
<li>hello3</li>
<li>hello4</li>
<li>hello5</li>
</ul>
</div>
</div>
data:
isBlur: true,
isUnfold: false,
methods:
getList() {
if (this.isUnfold) {
return
}
this.isBlur = false
this.$refs.selectBox.focus()
this.isUnfold = true
},
handleBlur() {
this.isBlur = true
setTimeout(() => {
this.isUnfold = false
}, 200)
}
CSS:
.selected-box {
width: 500px;
min-height: 0;
max-height: 0;
overflow: hidden;
outline: none;
transition: all 0.3s;
}
ul {
background-color: white;
list-style: none;
margin: 0;
padding: 0;
padding-inline-start: 0;
}
li {
background-color: blue;
list-style: none;
height: 20px;
line-height: 20px;
}
由于Blur触发会比click早所以控制div显示和展开就通过blur事件触发。通过isUnfold确定是否展开完成。由于设置了0.3秒(300ms)的动效,所以设置setTimeout延迟200ms。为什么不是300ms呢?因为从blur事件触发,到click事件,需要差不多80ms左右。所以设置200ms也够了。