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 相关文章推荐
IE8 兼容性问题(属性名区分大小写)
Jun 04 Javascript
jQuery插件实现大图全屏图片相册
Mar 14 Javascript
实例解析jQuery插件EasyUI最常用的表单验证规则
Nov 29 Javascript
延时加载JavaScript代码提高速度
Dec 27 Javascript
在Html中使用Requirejs进行模块化开发实例详解
Apr 15 Javascript
JavaScript 基础函数_深入剖析变量和作用域
May 18 Javascript
jQuery基础知识点总结(必看)
May 31 Javascript
jQuery Masonry瀑布流插件使用方法详解
Jan 18 Javascript
一个有意思的鼠标点击文字特效jquery代码
Sep 23 jQuery
JS实现定时任务每隔N秒请求后台setInterval定时和ajax请求问题
Oct 15 Javascript
微信小程序云开发实现增删改查功能
May 17 Javascript
vue实现点击出现操作弹出框的示例
Nov 05 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实现链结人气统计
2006/10/09 PHP
PHP配置心得包含MYSQL5乱码解决
2006/11/20 PHP
php递归删除目录下的文件但保留的实例分享
2014/05/10 PHP
php array_walk 对数组中的每个元素应用用户自定义函数详解
2016/11/18 PHP
?牟┛途W扣了一??效果出?? target=
2007/05/27 Javascript
Javascript valueOf 使用方法
2008/12/28 Javascript
input+select(multiple) 实现下拉框输入值
2009/05/21 Javascript
修复bash漏洞的shell脚本分享
2014/12/31 Javascript
浅谈Jquery核心函数
2015/06/18 Javascript
JS操作XML实例总结(加载与解析XML文件、字符串)
2015/12/08 Javascript
解决jQuery ajax请求在IE6中莫名中断的问题
2016/06/20 Javascript
使用ajaxfileupload.js实现上传文件功能
2016/08/13 Javascript
js中获取键盘事件的简单实现方法
2016/10/10 Javascript
JS动态计算移动端rem的解决方案
2016/10/14 Javascript
Element-ui upload上传文件限制的解决方法
2021/01/22 Javascript
python中使用pyhook实现键盘监控的例子
2014/07/18 Python
Python实现的简单hangman游戏实例
2015/06/28 Python
Python编程实现生成特定范围内不重复多个随机数的2种方法
2017/04/14 Python
Numpy掩码式数组详解
2018/04/17 Python
python3 cvs将数据读取为字典的方法
2018/12/22 Python
python抓取网页内容并进行语音播报的方法
2018/12/24 Python
Python实现的旋转数组功能算法示例
2019/02/23 Python
Django模板Templates使用方法详解
2019/07/19 Python
Python PyQt5运行程序把输出信息展示到GUI图形界面上
2020/04/27 Python
python如何更新包
2020/06/11 Python
Python 实现键盘鼠标按键模拟
2020/11/18 Python
matplotlib绘制正余弦曲线图的实现
2021/02/22 Python
python利用后缀表达式实现计算器功能
2021/02/22 Python
幼儿园大班开学教师寄语
2014/04/03 职场文书
幼儿园运动会口号
2014/06/07 职场文书
小组口号大全
2014/06/09 职场文书
计算机毕业大学生求职信
2014/06/26 职场文书
2014村书记党建工作汇报材料
2014/11/02 职场文书
歼十出击观后感
2015/06/11 职场文书
某某店铺的开业庆典主持词范本
2019/11/25 职场文书
一篇带你入门Java垃圾回收器
2021/06/16 Java/Android