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 相关文章推荐
如何使用JS获取IE上传文件路径(IE7,8)
Jul 08 Javascript
浅析XMLHttpRequest的缓存问题
Dec 13 Javascript
JavaScript中对象property的删除方法介绍
Dec 30 Javascript
js兼容火狐获取图片宽和高的方法
May 21 Javascript
一些实用性较高的js方法
Apr 19 Javascript
JavaScript的Backbone.js框架入门学习指引
May 07 Javascript
jQuery+Ajax+PHP弹出层异步登录效果(附源码下载)
May 27 Javascript
JavaScript中防止微信浏览器被整体拖动的方法
Aug 25 Javascript
tsconfig.json配置详解
May 17 Javascript
如何实现双向绑定mvvm的原理实现
May 28 Javascript
js实现多张图片每隔一秒切换一张图片
Jul 29 Javascript
vue解决使用$http获取数据时报错的问题
Oct 30 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解码unicode编码的中文字符代码分享
2014/08/13 PHP
PHP+MySql+jQuery实现的&quot;顶&quot;和&quot;踩&quot;投票功能
2016/05/21 PHP
PHP实现针对日期,月数,天数,周数,小时,分,秒等的加减运算示例【基于strtotime】
2017/04/19 PHP
Laravel如何自定义command命令浅析
2019/03/23 PHP
仿中关村在线首页弹出式广告插件(jQuery版)
2012/05/03 Javascript
js获取某元素的class里面的css属性值代码
2014/01/16 Javascript
JavaScript学习笔记(三):JavaScript也有入口Main函数
2015/09/12 Javascript
深入探究AngularJS框架中Scope对象的超级教程
2016/01/04 Javascript
微信小程序 教程之模块化
2016/10/17 Javascript
浅谈Node.js:fs文件系统模块
2016/12/08 Javascript
vue2组件实现懒加载浅析
2017/03/29 Javascript
laydate 显示结束时间不小于开始时间的实例
2017/08/11 Javascript
jQuery实现动画、消失、显现、渐出、渐入效果示例
2018/09/06 jQuery
使用vue 国际化i18n 实现多实现语言切换功能
2018/10/11 Javascript
微信小程序开发的基本流程步骤
2019/01/31 Javascript
openLayer4实现动态改变标注图标
2020/08/17 Javascript
python任务调度实例分析
2015/05/19 Python
解决Tensorflow使用pip安装后没有model目录的问题
2018/06/13 Python
pycham查看程序执行的时间方法
2018/11/29 Python
对python3.4 字符串转16进制的实例详解
2019/06/12 Python
Python通过cv2读取多个USB摄像头
2019/08/28 Python
python 链接sqlserver 写接口实例
2020/03/11 Python
Python虚拟环境的创建和使用详解
2020/09/07 Python
利用python查看数组中的所有元素是否相同
2021/01/08 Python
利用CSS3伪元素实现逐渐发光的方格边框
2017/05/07 HTML / CSS
台湾租车首选品牌:IWS艾维士租车
2019/05/03 全球购物
卫校毕业生自我鉴定
2013/10/31 职场文书
法学专业毕业生自荐信范文
2013/12/18 职场文书
甜点店创业计划书
2014/01/27 职场文书
聚美优品陈欧广告词
2014/03/14 职场文书
租房合同协议书
2014/04/09 职场文书
大学生逃课检讨书
2015/05/04 职场文书
主婚人致辞精选
2015/07/28 职场文书
matplotlib之pyplot模块实现添加子图subplot的使用
2021/04/25 Python
基于Python实现的购物商城管理系统
2021/04/27 Python
react如何快速设置文件路径别名
2021/04/28 Javascript