https://github.com/ElemeFE/element/blob/d419e260d0fc1463ccbc4f5e45e129ec0e972255/src/utils/clickoutside.js
下面的代码是element ui中的clickoutside.js
const on = (function() { if (!Vue.prototype.$isServer && document.addEventListener) { return function(element, event, handler) { if (element && event && handler) { element.addEventListener(event, handler, false); } }; } else { return function(element, event, handler) { if (element && event && handler) { element.attachEvent(‘on‘ + event, handler); } }; } })(); import Vue from ‘vue‘; const nodeList = []; const ctx = ‘@@clickoutsideContext‘; let startClick; let seed = 0; !Vue.prototype.$isServer && on(document, ‘mousedown‘, e => (startClick = e)); !Vue.prototype.$isServer && on(document, ‘mouseup‘, e => { nodeList.forEach(node => node[ctx].documentHandler(e, startClick)); }); function createDocumentHandler(el, binding, vnode) { return function(mouseup = {}, mousedown = {}) { console.log(vnode.context.popperElm) if (!vnode || !vnode.context || !mouseup.target || !mousedown.target || el.contains(mouseup.target) || el.contains(mousedown.target) || el === mouseup.target || (vnode.context.popperElm && (vnode.context.popperElm.contains(mouseup.target) || vnode.context.popperElm.contains(mousedown.target)))){ return; } console.log(binding.expression); if (binding.expression && el[ctx].methodName && vnode.context[el[ctx].methodName]) { vnode.context[el[ctx].methodName](); } else { el[ctx].bindingFn && el[ctx].bindingFn(); } }; } /** * v-clickoutside * @desc 点击元素外面才会触发的事件 * @example * ```vue * <div v-element-clickoutside="handleClose"> * ``` */ export default { bind(el, binding, vnode) { nodeList.push(el); const id = seed++; el[ctx] = { id, documentHandler: createDocumentHandler(el, binding, vnode), methodName: binding.expression, bindingFn: binding.value }; }, update(el, binding, vnode) { el[ctx].documentHandler = createDocumentHandler(el, binding, vnode); el[ctx].methodName = binding.expression; el[ctx].bindingFn = binding.value; }, unbind(el) { let len = nodeList.length; for (let i = 0; i < len; i++) { if (nodeList[i][ctx].id === el[ctx].id) { nodeList.splice(i, 1); break; } } delete el[ctx]; } };
这个是我写的alert.vue
<template> <div class=‘dialog-alert‘ v-show="alert"> <div class=‘dialog-content‘v-clickoutside="hideAlert"> <div class="dialog-body">{{message}}</div> <a href="javascript:;" class="dialog-button" @click="hideAlert">确定</a> </div> <div class="dialog-mask"></div> </div> </template> <script> import clickoutside from‘./../directives/vue-directive-clickout.js‘ export default{ props:{ alert:{ type:Boolean, required: true }, message:{ type:String, required: true } }, methods:{ hideAlert() { this.$emit(‘hideAlert‘); } }, directives: { clickoutside }, } </script> <style lang="scss" rel="stylesheet/scss" scoped> .dialog-alert { z-index: 21px; .dialog-content { position: absolute; left: 50%; top: 50%; margin-left: -4.6875rem; margin-top: -1.734375rem; z-index: 21; border-radius: .3125rem; background-color: #fff; } .dialog-body, .dialog-button { width: 9.375rem; height: 1.734375rem; margin: 0 auto; line-height: 1.734375rem; } .dialog-body { border-bottom: 1px solid #999; color: #6c6c6c } .dialog-button { color: #ff5000 } } .dialog-mask { position: absolute; width: 100%; height: 100%; top: 0; left: 0; bottom: 0; z-index: 20; background: rgba(0, 0, 0, .6) } </style>
还有我在login.vue中写的触发条件;loginIn函数是将alert的值改为true,hideAlert是将alert的值设置为false
<button class="btn-login" type="button" @click="loginIn">登录</button> <alert :alert="alert" message="wowoowow" @hideAlert=‘hideAlert‘></alert>
这里的我的问题就是为什么点击登录的时候,弹窗还出的来;点击的时候hideAlert被执行了 所以应该是false;所以呢我就就行了各种的测试,始终找不到答案。
最后呢?我在走路回家的路上想通了这个问题,因为mouseup、mousedown先执行的,click时间后执行的。有点小难受。
<!doctype html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0"> <meta http-equiv="X-UA-Compatible" content="ie=edge"> <title>Document</title> </head> <body> <div id="bbb">点击</div> <script> document.getElementById(‘bbb‘).addEventListener(‘click‘, function(){ console.log(‘click‘) }, false); document.addEventListener(‘mouseup‘, function(){ console.log(‘mouseup‘) }, false); document.addEventListener(‘mousedown‘, function(){ console.log(‘mousedown‘) }, false); </script> </body> </html>
结果:
测试的结果就是: clickoutside.js
1、当一个指令在同一页面上有多个时;绑定的是document事件;document的时间被重复触发;
原文地址:https://www.cnblogs.com/heyinwangchuan/p/8124438.html
时间: 2024-10-16 15:48:09