根據directive提供的API來寫一個點擊外部區域可以讓其下拉列表消失的菜單
<div id="app" v-clock>
<div class="main" v-clickoutside="handleClose">
<button @click="show = !show">點擊顯示下拉菜單</button>
<div class="dropdown" v-show="show">
<p>下拉框內容,點擊外面區域可以關閉</p>
</div>
</div>
var app = new Vue({
el: '#app',
data: {
show: false
},
methods: {
handleClose() {
this.show = false;
}
}
})
Vue.directive('clickoutside', {
bind: function(el, binding, vode) {
function documentHandler (e) {
if (el.contains(e.target)) {
return false
}
if (binding.expression) {
binding.value(e)
}
}
el.__vueClickOutSide__ = documentHandler
document.addEventListener('click', documentHandler)
},
unbind: function(el, binding) {
document.removeEventListener('click', el.__vueClickOutSide__)
delete el.__vueClickOutSide__
}
})
要在document上綁定click事件,所以在bind鉤子內聲明瞭一個函數documentHandler,並將它作爲句柄定在document的click事件上。documentHandler函數做了兩個判斷,第一個是判斷點擊的區域是否是指令所在的元素內部,如果是,就跑出函數,不信下繼續執行
contains方法是用來判斷元素A是否包含了元素 B,包含返回true,不包含返回false
<div id="parent">
父元素
<div id="children">子元素</div>
</div>
var a = doucment.getElemengById('parent')
var b = doucment.getElemengById('children')
console.log(A.contains(B)) // true
console.log(B.contains(A)) // false
第二個判斷是當前 的指令v-clickoutside有沒有寫表達式,在該自定義指令中,表達 式應該是第一個函數 ,在過濾了內部元素後,點擊外面任何區域應該招待用戶表達 式中的函數 ,所以binding.value就用來執行上下文methods中指定的函數的
參考: https://www.jb51.net/article/127236.htm