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 检测浏览器和操作系统的脚本
Dec 26 Javascript
基于jquery的loading 加载提示效果实现代码
Sep 01 Javascript
Javascript中的delete介绍
Sep 02 Javascript
防止登录页面出现在frame中js代码
Jul 22 Javascript
JavaScript的Ext JS框架中的GridPanel组件使用指南
May 21 Javascript
Vue学习笔记进阶篇之vue-router安装及使用方法
Jul 19 Javascript
Vue2.0 vue-source jsonp 跨域请求
Aug 04 Javascript
vue2+el-menu实现路由跳转及当前项的设置方法实例
Nov 07 Javascript
js与jQuery实现获取table中的数据并拼成json字符串操作示例
Jul 12 jQuery
JS实现全屏预览F11功能的示例代码
Jul 23 Javascript
NestJs 静态目录配置详解
Mar 12 Javascript
jquery向后台提交数组的代码分析
Feb 20 jQuery
浅谈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 抓取网页图片并且另存为的实现代码
2010/03/24 PHP
基于PHP静态类的原罪详解
2013/05/06 PHP
php5.3 注意事项说明
2013/07/01 PHP
利用中国天气预报接口实现简单天气预报
2014/01/20 PHP
php检测useragent版本示例
2014/03/24 PHP
ThinkPHP的Widget扩展实例
2014/06/19 PHP
常用PHP框架功能对照表
2014/10/23 PHP
CodeIgniter删除和设置Cookie的方法
2015/04/07 PHP
javascript学习笔记(九)javascript中的原型(prototype)及原型链的继承方式
2011/04/12 Javascript
jQuery EasyUI API 中文文档 - MenuButton菜单按钮使用介绍
2011/10/06 Javascript
在firefox和Chrome下关闭浏览器窗口无效的解决方法
2014/01/16 Javascript
JS实现清除指定cookies的方法
2014/09/20 Javascript
使用js画图之圆、弧、扇形
2015/01/12 Javascript
jquery中change()用法实例分析
2015/02/06 Javascript
js实现图片漂浮效果的方法
2015/03/02 Javascript
用js编写的简单的计算器代码程序
2015/08/04 Javascript
详解JavaScript逻辑And运算符
2015/12/04 Javascript
微信小程序实现拖拽 image 触摸事件监听的实例
2017/08/17 Javascript
axios post提交formdata的实例
2018/03/16 Javascript
vue+express 构建后台管理系统的示例代码
2018/07/19 Javascript
示例vue 的keep-alive缓存功能的实现
2018/12/13 Javascript
nodejs log4js 使用详解
2019/05/31 NodeJs
在JavaScript中使用严格模式(Strict Mode)
2019/06/13 Javascript
jquery实现下载图片功能
2019/07/18 jQuery
jQuery实现图片切换效果
2020/10/19 jQuery
Python基于正则表达式实现检查文件内容的方法【文件检索】
2017/08/30 Python
Pandas 同元素多列去重的实例
2018/07/03 Python
Flask Web开发入门之文件上传(八)
2018/08/17 Python
python中watchdog文件监控与检测上传功能
2020/10/30 Python
雅萌 (YA-MAN) :日本美容家电领域的龙头企业
2017/05/12 全球购物
Charles&Keith美国官方网站:新加坡快时尚鞋类和配饰零售商
2019/11/27 全球购物
Douglas意大利官网:购买香水和化妆品
2020/05/27 全球购物
金讯Java笔试题目
2013/06/18 面试题
python自然语言处理之字典树知识总结
2021/04/25 Python
详解Python类和对象内容
2021/06/22 Python
分享python函数常见关键字
2022/04/26 Python