js 下拉菜單點(diǎn)擊旁邊收起實(shí)現(xiàn)(踩坑記)
背景:
最近在搞一個需求:搜索框,輸入時顯示聯(lián)想詞下拉列表,當(dāng)點(diǎn)擊聯(lián)想詞跳轉(zhuǎn)到搜索頁,如果點(diǎn)擊其他部分收起聯(lián)想的下拉列表。接到需求后第一反應(yīng)用失焦(blur)去做收起操作避免body的監(jiān)控,隨后就踩坑里了,下面情景再現(xiàn),一步一步來看這個問題的解決(里面的demo等會用vue實(shí)現(xiàn))
帶有bug的版本演示圖
備注:最后的搜索跳轉(zhuǎn)我直接用console代替掉了,但是并沒有執(zhí)行
問題拋出
當(dāng)我點(diǎn)擊上面的聯(lián)想詞的時候它的onSearch并不能執(zhí)行
demo代碼展示
<template lang="html"> <div :class="[baseClass + '-wrap']"> <input type="text" v-model="searchVal" :class="[baseClass + '-input']" ref="demo-search-input" placeholder="搜索" @focus="onFoucs" @blur="onBlur" @keyup.enter="onSearch" @input="getRecommendedList" /> <span :class="[baseClass + '-btn']" @click="onSearch"></span> <div :class="[baseClass + '-recommended']" v-show="isShowRecommend && recommendList.length > 0"> <div :class="[baseClass + '-triangle-border', baseClass + '-tb-border']"></div> <div :class="[baseClass + '-triangle-border', baseClass + '-tb-bg']"></div> <ul :class="[baseClass + '-list-wrap']"> <li :class="[baseClass + '-list']" v-for="(item, index) in recommendList" :key="index" @click="onSearch(item)" >{{item}}</li> </ul> </div> </div> </template>
<script> const mockData = ['123456', '12', '56873', '092341', '454666677'] export default { data () { return { baseClass: 'demo-search', searchVal: '', isShowRecommend: false, recommendList: [] } }, methods: { onFoucs () { this.isShowRecommend = true }, onBlur () { this.isShowRecommend = false this.searchVal = '' this.recommendList = [] }, onSearch (val) { val = typeof val === 'string' ? val : this.searchVal if (val) { // 這里需要跳轉(zhuǎn)搜索,我們用console來代替 console.log(val) this.searchVal = '' } else { this.$refs['demo-search-input'].focus() } }, getRecommendedList () { if (this.searchVal) { // 這里需要給后臺發(fā)送請求來獲取聯(lián)想詞,這里我們用mock數(shù)據(jù)匹配來展示 setTimeout(() => { const reg = new RegExp(this.searchVal) const arr = [] for (let i = 0; i < mockData.length; i++) { if (reg.test(mockData[i])) { arr.push(mockData[i]) } } this.recommendList = arr }, 10) } } } } </script>
上面就是我們這個效果的代碼了,根據(jù)邏輯來看我們在input上面綁定了blur事件來控制清空搜索和收起聯(lián)想詞下拉列表,同時給list綁定了click事件,我們的預(yù)期是點(diǎn)擊list的時候console執(zhí)行然后input失去焦點(diǎn)收起來,但是事實(shí)是它僅僅執(zhí)行了blur,onSearch事件里面的console并未執(zhí)行。
猜測原因做嘗試
首先第一反應(yīng)絕對是事件的觸發(fā)順序,所以我就想到了利器setTimeout來驗(yàn)證
onBlur () { setTimeout(() => { this.isShowRecommend = false this.searchVal = '' this.recommendList = [] }, 500) }
結(jié)果果然觸發(fā)了,因?yàn)檠舆t了blur先執(zhí)行了click。但是當(dāng)我們點(diǎn)擊其他區(qū)域的時候下拉窗口需要停頓一會再消失,這個很詭異,所以繼續(xù)想辦法調(diào)整。
分析:
- 現(xiàn)在確認(rèn)是事件的優(yōu)先級的問題了,blur要優(yōu)先于click所以我們需要想辦法替換掉click
- 我們知道click事件是由mousedown事件和mouseup事件組成,同時mousedown和mouseup觸發(fā)必須在同一個像素點(diǎn)上才會觸發(fā)click事件。即鼠標(biāo)點(diǎn)擊: mousedown -> mouseup -> click
- 所以我們來寫一個demo看一下事件的執(zhí)行順序
methods: { onClick () { console.log('click') }, onMousedown () { console.log('mousedown') }, onMouseup () { console.log('mouseup') }, onBlur () { console.log('blur') } }
結(jié)果
最后把click替換成mousedown,完成了問題修復(fù)
<li :class="[baseClass + '-list']" v-for="(item, index) in recommendList" :key="index" @mousedown="onSearch(item)" >{{item}}</li>
最終效果展示
好了今天的踩坑和填坑運(yùn)動結(jié)束,以上就是本文的全部內(nèi)容,希望對大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
- JavaScript實(shí)現(xiàn)HTML導(dǎo)航欄下拉菜單
- JavaScript實(shí)現(xiàn)網(wǎng)頁下拉菜單效果
- Vue.js下拉菜單組件使用方法詳解
- 淺談Vue.js中如何實(shí)現(xiàn)自定義下拉菜單指令
- js實(shí)現(xiàn)按鈕開關(guān)單機(jī)下拉菜單效果
- js動態(tài)設(shè)置select下拉菜單的默認(rèn)選中項(xiàng)實(shí)例
- 純JS實(shí)現(xiàn)出生日期[年月日]下拉菜單效果
- JS實(shí)現(xiàn)點(diǎn)擊下拉菜單把選擇的內(nèi)容同步到input輸入框內(nèi)的實(shí)例
- js阻止默認(rèn)右鍵的下拉菜單方法
- js面向?qū)ο蠓庋b級聯(lián)下拉菜單列表的實(shí)現(xiàn)步驟
相關(guān)文章
javascript 獲取url參數(shù)和script標(biāo)簽中獲取url參數(shù)函數(shù)代碼
不要在方法中調(diào)用方法,否則可能始終獲取的是最后一個js的文件的參數(shù),要在方法中使用,請先用變量保存,在方法中直接獲取2010-01-01JavaScript對象和字串之間的轉(zhuǎn)換實(shí)例探討
從對象的格式可以看出,如果字串的格式定義成 json 格式的, 就可以直接轉(zhuǎn)換為obj了,感興趣的朋友可以參考下哈2013-04-04線路分流自動智能跳轉(zhuǎn)代碼,自動選擇最快鏡像網(wǎng)站(js)
線路分流自動智能跳轉(zhuǎn)代碼,自動選擇最快鏡像網(wǎng)站,自動選擇電信或網(wǎng)通線路跳轉(zhuǎn)代碼2011-10-10關(guān)于驗(yàn)證碼在IE中不刷新的快速解決方法
下面小編就為大家?guī)硪黄P(guān)于驗(yàn)證碼在IE中不刷新的快速解決方法。小編覺得挺不錯的,現(xiàn)在就分享給大家,也給大家做個參考。一起跟隨小編過來看看吧2016-09-09javascript css紅色經(jīng)典選項(xiàng)卡效果實(shí)現(xiàn)代碼
這篇文章主要為大家詳細(xì)介紹了javascript css紅色經(jīng)典選項(xiàng)卡效果的實(shí)現(xiàn)代碼,需要的朋友可以參考下2016-05-05Web打印解決方案之證件套打的實(shí)現(xiàn)思路
這篇文章主要介紹了Web打印解決方案之證件套打的實(shí)現(xiàn)思路的相關(guān)資料,非常不錯,具有參考借鑒價值,需要的朋友可以參考下2016-08-08