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