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 相关文章推荐
JavaScript的变量作用域深入理解
Oct 25 Javascript
js判断运行jsp页面的浏览器类型以及版本示例
Oct 30 Javascript
Javascript基础教程之数据类型转换
Jan 18 Javascript
JavaScript实现网站访问次数统计代码
Aug 12 Javascript
JS实现的另类手风琴效果网页内容切换代码
Sep 08 Javascript
jQuery实现Email邮箱地址自动补全功能代码
Nov 03 Javascript
js倒计时抢购实例
Dec 20 Javascript
详解JS对象封装的常用方式
Dec 30 Javascript
jQuery Validate 数组 全部验证问题
Jan 12 Javascript
微信小程序中setInterval的使用方法
Sep 29 Javascript
五步轻松实现JavaScript HTML时钟效果
Mar 25 Javascript
Vue.js 图标选择组件实践详解
Dec 03 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
用来给图片加水印的PHP类
2008/04/09 PHP
php 生成随机验证码图片代码
2010/02/08 PHP
在PHP中利用wsdl创建标准webservice的实现代码
2011/12/07 PHP
PHP防止刷新重复提交页面的示例代码
2015/11/11 PHP
学习php设计模式 php实现桥梁模式(bridge)
2015/12/07 PHP
深入理解Yii2.0乐观锁与悲观锁的原理与使用
2017/07/26 PHP
jquery tools 系列 scrollable(2)
2009/09/06 Javascript
该如何加载google-analytics(或其他第三方)的JS
2010/05/13 Javascript
jQuery 源码分析笔记(5) jQuery.support
2011/06/19 Javascript
node.js中的buffer.Buffer.isBuffer方法使用说明
2014/12/14 Javascript
快速学习jQuery插件 jquery.validate.js表单验证插件使用方法
2015/12/01 Javascript
Angular2  NgModule 模块详解
2016/10/19 Javascript
Bootstrap CSS布局之按钮
2016/12/17 Javascript
jQuery实现CheckBox全选、全不选功能
2017/01/11 Javascript
原生js实现电商侧边导航效果
2017/01/19 Javascript
vue+vux实现移动端文件上传样式
2017/07/28 Javascript
Vue手把手教你撸一个 beforeEnter 钩子函数
2018/04/24 Javascript
Windows下支持自动更新的Electron应用脚手架的方法
2018/12/24 Javascript
Ruby使用eventmachine为HTTP服务器添加文件下载功能
2016/04/20 Python
python安装oracle扩展及数据库连接方法
2017/02/21 Python
使用Python快速搭建HTTP服务和文件共享服务的实例讲解
2018/06/04 Python
强悍的Python读取大文件的解决方案
2019/02/16 Python
python异常触发及自定义异常类解析
2019/08/06 Python
基于python的selenium两种文件上传操作实现详解
2019/09/19 Python
python 正则表达式贪婪模式与非贪婪模式原理、用法实例分析
2019/10/14 Python
pyhton中__pycache__文件夹的产生与作用详解
2019/11/24 Python
三步解决python PermissionError: [WinError 5]拒绝访问的情况
2020/04/22 Python
python+selenium+chrome批量文件下载并自动创建文件夹实例
2020/04/27 Python
python 使用tkinter+you-get实现视频下载器
2020/11/17 Python
CSS3 box-sizing属性详解
2016/11/15 HTML / CSS
美国著名的婴儿学步鞋老品牌:Robeez
2016/08/20 全球购物
英国最大的LED专业零售商:Led Hut
2018/03/16 全球购物
JAVA代码查错题
2014/10/10 面试题
体育专业个人求职信范文
2013/12/27 职场文书
2015年档案室工作总结
2015/05/23 职场文书
深入详解JS函数的柯里化
2021/06/09 Javascript