Vue指令实现OutClick的示例


Posted in Javascript onNovember 16, 2020

原始实现

下面是两种常见的模态框的实现方式

方案一:默认 click 都是放在冒泡阶段,只要在内容区域上添加 click 的阻止冒泡即可

<div class="cover" @click="close">
 <!-- 阻止冒泡 -->
 <div class="content" @click.stop>modal content</div>
</div>

方案二:通过代码判断点击触发的 DOM 是否在内容区域内

<div class="cover" @click="handleClick">
 <div class="content" ref="content">modal content</div>
</div>
handleClick (e) {
 let clickOut = true
 let temp = e.target
 do {
  if (temp === this.$refs.content) {
   clickOut = false
   break
  }
  temp = temp.parentElement
 } while (temp !== document.documentElement)
 console.log(clickOut)
}

指令实现

上面的代码可以解决全屏的模态框点击外部区域关闭。但是还有一种 Pop 的弹出,这种弹出的外部区域不在本组件内,想要实现这种弹出的点击外部区域关闭用上面的方式二也是可以的,只需把 mounted 阶段把 handleClick 事件添加到 body,在 beforeDestroy 上解绑 body 上的点击时间就就可以了。

如果多个组件需要实现这点击外部区域关闭的效果,可以通过 Vue 的指令来进行封装

实现弹窗

<div class="cover">
 <div class="content" v-out-click="close">modal content</div>
</div>

实现弹出

<button @click="popIsShow = true">显示气泡</button>
<div class="pop" v-if="popIsShow" v-out-click="closePop">I'm pop text</div>

指令代码的具体内容如下。有一点比较难受的是指令里面没有地方能存放变量,只好把把这些变量放到了 DOM 上了。还有就是在使用的时候要加上v-的前缀,指令的名字不用带上v-

import outClick from './directive/out-click.js'
Vue.directive(outClick.name, outClick)
const KEY_OUT = '_out_click'
const KEY_OUT_EVENT = '_out_click_event'
const KEY_IN = '_in_click'
const KEY_FLAG = '_in_out_flag'

function removeEvent(el, binding, vnode) {
 el.removeEventListener('click', el[KEY_IN], false)
 window.removeEventListener('click', el[KEY_OUT], false)
 delete el[KEY_IN]
 delete el[KEY_OUT]
 delete el[KEY_OUT_EVENT]
 delete el[KEY_FLAG]
}

function initEvent(el, binding, vnode) {
 // setTimeout 0: 忽略点击外部的按钮初始化该组件时,触发的origin click
 setTimeout(() => {
  el[KEY_OUT] = () => outClick(el)
  el[KEY_IN] = () => inClick(el)
  el[KEY_OUT_EVENT] = binding.value
  el.addEventListener('click', el[KEY_IN], false)
  window.addEventListener('click', el[KEY_OUT], false)
 }, 0)
}

function inClick(el) {
 // 通过事件捕获的顺序作为标志位
 // 最好不要使用阻止冒泡来实现,那样会影响其他的click无法触发
 el[KEY_FLAG] = '1'
}

function outClick(el) {
 if (!el[KEY_FLAG] && el[KEY_OUT_EVENT]) {
  el[KEY_OUT_EVENT]()
 }
 delete el[KEY_FLAG]
}

export default {
 name: 'out-click',
 update: (el, binding, vnode) => {
  if (binding.value === binding.oldValue) {
   return
  }
  removeEvent(el, binding, vnode)
  initEvent(el, binding, vnode)
 },
 bind: initEvent,
 unbind: removeEvent
}

以上就是Vue指令实现OutClick的示例的详细内容,更多关于Vue指令实现OutClick的资料请关注三水点靠木其它相关文章!

Javascript 相关文章推荐
在 IE 中调用 javascript 打开 Excel 表
Dec 21 Javascript
jQuery 顺便学习下CSS选择器 奇偶匹配nth-child(even)
May 24 Javascript
解决jquery的.animate()函数在IE6下的问题
Dec 03 Javascript
深入理解JavaScript系列(7) S.O.L.I.D五大原则之开闭原则OCP
Jan 15 Javascript
js怎么终止程序return不行换jfslk
May 30 Javascript
jQuery中map()方法用法实例
Jan 06 Javascript
使用jQuery实现图片遮罩半透明坠落遮挡
Mar 16 Javascript
基于jQuery插件jqzoom实现的图片放大镜效果示例
Jan 23 Javascript
浅谈Node.js CVE-2017-14849 漏洞分析(详细步骤)
Nov 10 Javascript
vue2 router 动态传参,多个参数的实例
Nov 10 Javascript
vue-cli2打包前和打包后的css前缀不一致的问题解决
Aug 24 Javascript
用Object.prototype.toString.call(obj)检测对象类型原因分析
Oct 11 Javascript
浅谈vue在html中出现{{}}的原因及解决方式
Nov 16 #Javascript
vue组件中传值EventBus的使用及注意事项说明
Nov 16 #Javascript
小程序自定义弹框效果
Nov 16 #Javascript
vuex中遇到的坑,vuex数据改变,组件中页面不渲染操作
Nov 16 #Javascript
基于Vue+Webpack拆分路由文件实现管理
Nov 16 #Javascript
小程序实现上下切换位置
Nov 16 #Javascript
小程序实现点击tab切换左右滑动
Nov 16 #Javascript
You might like
解析dedecms空间迁移步骤详解
2013/05/15 PHP
json 定义
2008/06/10 Javascript
jQuery入门问答 整理的几个常见的初学者问题
2010/02/22 Javascript
ajax更新数据后,jquery、jq失效问题
2011/03/16 Javascript
jQuery中:eq()选择器用法实例
2014/12/29 Javascript
原生js实现数字字母混合验证码的简单实例
2015/12/10 Javascript
JS清除文本框内容离开在恢复及鼠标离开文本框时触发js的方法
2016/01/12 Javascript
jquery实现简单的banner轮播效果【实例】
2016/03/30 Javascript
详解jQuery中的deferred对象的使用(一)
2016/05/27 Javascript
一个仿微博登陆邮箱提示框js开发案例
2016/07/28 Javascript
微信小程序 闭包写法详细介绍
2016/12/14 Javascript
JS如何设置元素样式的方法示例
2017/08/28 Javascript
SelectPage v2.4 发布新增纯下拉列表和关闭分页功能
2017/09/07 Javascript
javaScript 连接打印机,打印小票的实例
2017/12/29 Javascript
Vue+webpack+Element 兼容问题总结(小结)
2018/08/16 Javascript
Node.js Event Loop各阶段讲解
2019/03/08 Javascript
关于js陀螺仪的理解分析
2019/04/11 Javascript
Jquery让form表单异步提交代码实现
2019/11/14 jQuery
[06:45]DOTA2-DPC中国联赛 正赛 Magma vs LBZS 选手采访
2021/03/11 DOTA
python使用socket进行简单网络连接的方法
2015/04/29 Python
Python+MongoDB自增键值的简单实现
2016/11/04 Python
mac 安装python网络请求包requests方法
2018/06/13 Python
对Tensorflow中权值和feature map的可视化详解
2018/06/14 Python
Python列表切片操作实例总结
2019/02/19 Python
对Python3中列表乘以某一个数的示例详解
2019/07/20 Python
python 命名规范知识点汇总
2020/02/14 Python
HTML5 在canvas中绘制文本附效果图
2014/06/23 HTML / CSS
eDreams巴西:廉价机票,酒店优惠和度假套餐
2017/04/14 全球购物
android面试问题与答案
2016/12/27 面试题
动漫专业高职生职业生涯规划书
2014/02/15 职场文书
2014年节能工作总结
2014/12/18 职场文书
2015年乡镇扶贫工作总结
2015/04/08 职场文书
合同范本之电脑出租
2019/08/13 职场文书
nginx location优先级的深入讲解
2021/03/31 Servers
厉害!这是Redis可视化工具最全的横向评测
2021/07/15 Redis
Windows Server 2019 安装DHCP服务及相关配置
2022/04/28 Servers