1. 程式人生 > 其它 >js div span等節點新增focus聚焦、blur失焦事件(tabindex屬性)

js div span等節點新增focus聚焦、blur失焦事件(tabindex屬性)

場景:下拉彈框顯示時,想要點選其他地方即隱藏(不使用蒙板,下拉彈框定位到點選顯示的位置)

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