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 相关文章推荐
jQuery EasyUI API 中文文档 - Parser 解析器
Sep 29 Javascript
autoPlay 基于jquery的图片自动播放效果
Dec 07 Javascript
javascript 获取HTML DOM父、子、临近节点
Jun 16 Javascript
Highcharts 多个Y轴动态刷新数据的实现代码
May 28 Javascript
微信小程序 网络API发起请求详解
Nov 09 Javascript
JavaScript给每一个li节点绑定点击事件的实现方法
Dec 01 Javascript
微信小程序富文本渲染引擎的详解
Sep 30 Javascript
react-native fetch的具体使用方法
Nov 01 Javascript
仿京东快报向上滚动的实例
Dec 13 Javascript
详解使用 Node.js 开发简单的脚手架工具
Jun 08 Javascript
ES6入门教程之Array.from()方法
Mar 23 Javascript
Vue组件通信入门之Provide和Inject机制
Dec 29 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
PHP5与MySQL数据库操作常用代码 收集
2010/03/21 PHP
WordPress中&quot;无法将上传的文件移动至&quot;错误的解决方法
2015/07/01 PHP
PHP实现Redis单据锁以及防止并发重复写入
2018/04/10 PHP
Thinkphp5框架中引入Markdown编辑器操作示例
2020/06/03 PHP
让你的PHP,APACHE,NGINX支持大文件上传
2021/03/09 PHP
jQuery 关于伪类选择符的使用说明
2013/04/24 Javascript
js数组与字符串的相互转换方法
2014/07/09 Javascript
分享一款基于jQuery的视频播放插件
2014/10/09 Javascript
jQuery大于号(&gt;)选择器的作用解释
2015/01/13 Javascript
深入JavaScript高级程序设计之对象、数组(栈方法,队列方法,重排序方法,迭代方法)
2015/12/01 Javascript
AngularJS基础 ng-href 指令用法
2016/08/01 Javascript
如何在Angular.JS中接收并下载PDF
2016/11/26 Javascript
jQuery简单实现遍历单选框的方法
2017/03/06 Javascript
详解nodejs爬虫程序解决gbk等中文编码问题
2017/04/06 NodeJs
Bootstrap + AngularJS 实现简单的数据过滤字符查找功能
2017/07/27 Javascript
webpack@v4升级踩坑(小结)
2018/10/08 Javascript
一文秒懂nodejs中的异步编程
2021/01/28 NodeJs
Python实现PS图像明亮度调整效果示例
2018/01/23 Python
Python图像处理之直线和曲线的拟合与绘制【curve_fit()应用】
2018/12/26 Python
在numpy矩阵中令小于0的元素改为0的实例
2019/01/26 Python
Python把对应格式的csv文件转换成字典类型存储脚本的方法
2019/02/12 Python
Python面向对象进阶学习
2019/05/21 Python
Python函数装饰器原理与用法详解
2019/08/16 Python
Golang GBK转UTF-8的例子
2019/08/26 Python
Pytorch .pth权重文件的使用解析
2020/02/14 Python
新西兰领先的内衣店:Bendon Lingerie新西兰
2018/07/11 全球购物
美国领先的机场停车聚合商:Airport Parking Reservations
2020/02/28 全球购物
绿化先进工作者事迹材料
2014/01/30 职场文书
校园文明标语
2014/06/13 职场文书
租房协议书样本
2014/08/20 职场文书
法院四风对照检查材料思想汇报
2014/10/06 职场文书
2015新年寄语(一句话)
2014/12/08 职场文书
党员先进事迹材料
2014/12/19 职场文书
PHP使用非对称加密算法RSA
2021/04/21 PHP
关于k8s环境部署mysql主从的问题
2022/03/13 MySQL
《黑岩★★射手 DAWN FALL》BD发售宣传CM公开
2022/04/04 日漫