記錄一個vue directive實現點擊指令外部區域調用函數的方案

 根據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

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章