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 相关文章推荐
解决使用attachEvent函数时,this指向被绑定的元素的问题的方法
Aug 13 Javascript
理解JavaScript的caller,callee,call,apply
Apr 28 Javascript
js匿名函数的调用示例(形式多种多样)
Aug 20 Javascript
常见的javascript跨域通信方法
Dec 31 Javascript
JS代码实现table数据分页效果
May 26 Javascript
手机端图片缩放旋转全屏查看PhotoSwipe.js插件实现
Aug 25 Javascript
Java与JavaScript中判断两字符串是否相等的区别
Mar 13 Javascript
纯js实现的积木(div层)拖动功能示例
Jul 19 Javascript
vue视频播放插件vue-video-player的具体使用方法
Nov 08 Javascript
js实现多个标题吸顶效果
Jan 08 Javascript
jQuery实现移动端图片上传预览组件的方法分析
May 01 jQuery
vue 判断元素内容是否超过宽度的方式
Jul 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
PHP 加密/解密函数 dencrypt(动态密文,带压缩功能,支持中文)
2009/01/30 PHP
理解Javascript_02_理解undefined和null
2010/10/11 Javascript
基于Jquery的开发个代阴影的对话框效果代码
2011/07/28 Javascript
jquery写个checkbox——类似邮箱全选功能
2013/03/19 Javascript
提高jQuery性能的十个诀窍
2013/11/14 Javascript
JavaScript使用cookie实现记住账号密码功能
2015/04/27 Javascript
node.js实现爬虫教程
2020/08/25 Javascript
一个例子轻松学会Vue.js
2017/01/02 Javascript
jQuery简单实现MD5加密的方法
2017/03/03 Javascript
详解Vue 非父子组件通信方法(非Vuex)
2017/05/24 Javascript
jQuery封装placeholder效果实现方法,让低版本浏览器支持该效果
2017/07/08 jQuery
动态Axios的配置步骤详解
2018/01/12 Javascript
浅谈Angularjs中不同类型的双向数据绑定
2018/07/16 Javascript
layui复选框的全选与取消实现方法
2019/09/02 Javascript
vue实现购物车加减
2020/05/30 Javascript
[49:43]VG vs FNATIC 2019国际邀请赛小组赛 BO2 第一场 8.15
2019/08/17 DOTA
Python中使用Boolean操作符做真值测试实例
2015/01/30 Python
Python的Tornado框架异步编程入门实例
2015/04/24 Python
Python基于Socket实现的简单聊天程序示例
2017/08/05 Python
Python实现获取本地及远程图片大小的方法示例
2018/07/21 Python
查看Python依赖包及其版本号信息的方法
2019/08/13 Python
python海龟绘图之画国旗实例代码
2020/11/11 Python
美国著名珠宝品牌之一:Jared The Galleria Of Jewelry
2016/10/01 全球购物
社会实践心得体会
2014/01/03 职场文书
微型企业创业投资计划书
2014/01/10 职场文书
美德好少年事迹材料
2014/01/19 职场文书
图书室标语
2014/06/21 职场文书
环保志愿者活动方案
2014/08/14 职场文书
单位法定代表人授权委托书
2014/09/20 职场文书
个人合伙协议书范本
2014/10/14 职场文书
小学生安全教育广播稿
2014/10/20 职场文书
护士年终个人总结
2015/02/13 职场文书
幼儿园辞职书
2015/02/26 职场文书
2015年仓库管理员工作总结
2015/04/21 职场文书
apache基于端口创建虚拟主机的示例
2021/04/24 Servers
html中相对位置与绝对位置的具体使用
2022/05/15 HTML / CSS