自定義導航欄菜單失焦

一個簡單的效果,點擊導航欄彈出菜單後,在菜單外點擊觸發失焦,自動關閉菜單css


本文采用Vant組件
核心:經過觸發菜單內的input聚焦失焦控制顯示/隱藏html

導航欄:

<van-nav-bar title="導航欄" left-arrow @click="handleRight">
    <van-icon name="ellipsis" v-slot:right />
</van-nav-bar>

菜單:

<div v-show="isShowMenu" class="nav-menu">
    <ul>
        <li v-for="item in menuList" 
            :key="item"
            @click="handleMenu(item)">{{ item }}</li>
    </ul>
    <input ref="MenuInput" type="text" @blur="menuBlur" />
</div>
.nav-menu{
    position: fixed;
    top: 40px;
    right: 5px;
    input{
        position: absolute;
        left: 0;
        bottom: 0;
        width: 0;
        height: 0;
        margin: 0;
        border: none;
        outline: 0;
        opacity: 0;
        -webkit-appearence: none;
    }
}

事件:

export default{
    name: 'custom-nav',
    data(){
        return {
            isShowMenu: false,// 控制菜單
            menuList: ['操做1', '操做2'],// 菜單
        }
    },
    methods: {
        handleMenu(item){// 點擊菜單項
            console.log(item)
        },
        menuBlur(){// 輸入框失焦 =》 隱藏菜單
            this.isShowMenu = false
        },
        handleRight(){// 點擊導航欄右側
            this.isShowMenu = !this.isShowMenu
            // trigger焦點
            this.$nextTick(() => {
                if(this.$refs.MenuInput){
                    this.$refs.MenuInput.focus()
                }else{
                    this.$refs.MenuInput.blur()
                }
            })
        }
    }
}

問題:

  1. 菜單欄點擊事件handleMenu與輸入框失焦menuBlur衝突web

    因爲js是單線程,因此二者沒法同時進行,加個延遲app

    menuBlur(){
        setTimeout(() => {
            this.isShowMenu = false;
        }, 100)
    }
  2. 輸入框聚焦同時彈出鍵盤
    若是把input類型設置爲hidden反而不能聚焦,因此加個只讀屬性readonlythis

    <input ref="MenuInput" readonly type="text" @blur="menuBlur" />
  3. 其餘組件同時出發失焦事件
    在用ElementUI的日期選擇器時,其自帶的@blur會上浮,不知道算不算bug。
    此處帶上事件修飾符可解決線程

    <el-date-picker @blur.native.capture="pickerBlur"></el-date-picker>
相關文章
相關標籤/搜索