js div span等節點新增focus聚焦、blur失焦事件(tabindex屬性)
阿新 • • 發佈:2021-06-19
場景:下拉彈框顯示時,想要點選其他地方即隱藏(不使用蒙板,下拉彈框定位到點選顯示的位置)
tabindex可以使得相應的節點具有 focus 和 blur 事件
tabindex=負值
(通常是tabindex='-1'),表示元素是可聚焦的,但是不能通過鍵盤導航來訪問到該元素,用JS做頁面小元件內部鍵盤導航的時候非常有用。
tabindex='0',
表示元素是可聚焦的,並且可以通過鍵盤導航來聚焦到該元素,它的相對順序是當前處於的DOM結構來決定的。
tabindex=正值,
表示元素是可聚焦的,並且可以通過鍵盤導航來訪問到該元素;它的相對順序按照tabindex 的數值遞增而滯後獲焦。如果多個元素擁有相同的 tabindex,它們的相對順序按照他們在當前DOM中的先後順序決定。
注:tabindex 的最大值不應超過 32767。如果沒有指定,它的預設值為 -1。
tabindex == -1 時無法通過tab鍵選中該節點
tabindex == 0 或 1 都可以通過tab鍵選中該節點(不同的賦值表示不同的優先順序)
template
<template> <div> <!-- 下拉框相關 --> <div class="drop-button-container" @click="switchDropDownBox" tabindex="0" @blur="blurFunc"> <div>{{ currentPreferenceLine }}</div> <div class="drop-button icon_drop"></div> <!-- 下拉彈框 --> <div class="drop-down-container drop-down-box-bg" v-if="isShowDropDownBox"> <div class="item" :class="item.isSelect ? 'primary-color' : 'base-text'" v-for="(item, index) in dropDownBoxData" :key="index" @click="swichPreferenceLine(index)"> {{item.text}} </div> </div> </div> </div> </template>
script方法
export default { name: 'UserProfit', computed: { // 獲取當前下拉框的選中項 currentPreferenceLine() { return this.dropDownBoxData.find(item => item.isSelect).text; } }, data() { return { // 下拉框選項資料 dropDownBoxData: [ { text: 'DOW J', isSelect: true, }, { text: 'S/P 500', isSelect: false }, { text: 'NASDAQ', isSelect: false }, ], // 是否顯示下拉框 isShowDropDownBox: false }; }, methods: { // 下拉框顯示和隱藏 switchDropDownBox() { this.isShowDropDownBox = !this.isShowDropDownBox; }, // 切換輔助線 -- 下拉框項的選擇 swichPreferenceLine(index) { for (const i in this.dropDownBoxData) { if (this.dropDownBoxData[i].hasOwnProperty('isSelect')) { this.dropDownBoxData[i].isSelect = false; } } if (this.dropDownBoxData[index].hasOwnProperty('isSelect')) { this.dropDownBoxData[index].isSelect = true; } }, // 下拉框隱藏 -- 使用tabindex的失去焦點 blurFunc() { window.console.log('blur'); this.isShowDropDownBox = false; } } }; </script>
下拉彈框佈局
<style lang='less' scoped>
.drop-button-container {
margin-left: 30px;
position: relative;
display: flex;
justify-content: center;
align-items: center;
.drop-button {
margin-left: 12px;
}
.drop-down-container {
position: absolute;
top: 4px;
right: 0;
z-index: 11;
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
width: 120px;
height: 120px;
box-shadow: 0px 3px 29px 0px rgba(59,74,116,0.14);
border-radius: 16px;
.item {
font-size: 16px;
line-height: 16px;
font-weight: 500;
padding: 6px 0;
}
}
.icon_drop {
width: 0;
height: 0;
border-left: 6px solid transparent;
border-right: 6px solid transparent;
border-top: 6px solid #000;
}
.drop-down-box-bg {
background-color: #e6e6e6;
}
.primary-color {
color: #fb7299,
}
.base-text {
color: #000
}
}
</style>
完整程式碼:
<template>
<div>
<!-- 下拉框相關 -->
<div class="drop-button-container" @click="switchDropDownBox" tabindex="0" @blur="blurFunc">
<div>{{ currentPreferenceLine }}</div>
<div class="drop-button icon_drop"></div>
<!-- 下拉彈框 -->
<div class="drop-down-container drop-down-box-bg" v-if="isShowDropDownBox">
<div
class="item"
:class="item.isSelect ? 'primary-color' : 'base-text'"
v-for="(item, index) in dropDownBoxData"
:key="index"
@click="swichPreferenceLine(index)">
{{item.text}}
</div>
</div>
</div>
</div>
</template>
<script>
export default {
name: 'UserProfit',
computed: {
// 獲取當前下拉框的選中項
currentPreferenceLine() {
return this.dropDownBoxData.find(item => item.isSelect).text;
}
},
data() {
return {
// 下拉框選項資料
dropDownBoxData: [
{
text: 'DOW J',
isSelect: true,
},
{
text: 'S/P 500',
isSelect: false
},
{
text: 'NASDAQ',
isSelect: false
},
],
// 是否顯示下拉框
isShowDropDownBox: false
};
},
methods: {
// 下拉框顯示和隱藏
switchDropDownBox() {
this.isShowDropDownBox = !this.isShowDropDownBox;
},
// 切換輔助線 -- 下拉框項的選擇
swichPreferenceLine(index) {
for (const i in this.dropDownBoxData) {
if (this.dropDownBoxData[i].hasOwnProperty('isSelect')) {
this.dropDownBoxData[i].isSelect = false;
}
}
if (this.dropDownBoxData[index].hasOwnProperty('isSelect')) {
this.dropDownBoxData[index].isSelect = true;
}
},
// 下拉框隱藏 -- 使用tabindex的失去焦點
blurFunc() {
window.console.log('blur');
this.isShowDropDownBox = false;
}
}
};
</script>
<style lang='less' scoped>
.drop-button-container {
margin-left: 30px;
position: relative;
display: flex;
justify-content: center;
align-items: center;
.drop-button {
margin-left: 12px;
}
.drop-down-container {
position: absolute;
top: 4px;
right: 0;
z-index: 11;
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
width: 120px;
height: 120px;
box-shadow: 0px 3px 29px 0px rgba(59,74,116,0.14);
border-radius: 16px;
.item {
font-size: 16px;
line-height: 16px;
font-weight: 500;
padding: 6px 0;
}
}
.icon_drop {
width: 0;
height: 0;
border-left: 6px solid transparent;
border-right: 6px solid transparent;
border-top: 6px solid #000;
}
.drop-down-box-bg {
background-color: #e6e6e6;
}
.primary-color {
color: #fb7299,
}
.base-text {
color: #000
}
}
</style>
https://blog.csdn.net/weixin_40532650/article/details/109534124