根據directive提供的API來寫一個點擊外部區域可讓其下拉列表消失的菜單javascript
<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函數作了兩個判斷,第一個是判斷點擊的區域是不是指令所在的元素內部,若是是,就跑出函數,不信下繼續執行html
contains方法是用來判斷元素A是否包含了元素 B,包含返回true,不包含返回falsevue
<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中指定的函數的java
參考: https://www.jb51.net/article/127236.htmexpress