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 相关文章推荐
表头固定(利用jquery实现原理介绍)
Nov 08 Javascript
jQuery在ul中显示某个li索引号的方法
Mar 17 Javascript
jquery对象与DOM对象转化
Feb 08 Javascript
Angular4项目中添加i18n国际化插件ngx-translate的步骤详解
Jul 02 Javascript
Bootstrap 模态对话框只加载一次 remote 数据的完美解决办法
Jul 09 Javascript
js学习总结之DOM2兼容处理重复问题的解决方法
Jul 27 Javascript
浅谈webpack下的AOP式无侵入注入
Nov 12 Javascript
JS div匀速移动动画与变速移动动画代码实例
Mar 26 Javascript
Vue+Koa2 打包后进行线上部署的教程详解
Jul 31 Javascript
微信小程序 组件的外部样式externalClasses使用详解
Sep 06 Javascript
vue集成openlayers加载geojson并实现点击弹窗教程
Sep 24 Javascript
使用PDF.js渲染canvas实现预览pdf的效果示例
Apr 17 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与浏览器缓存的分析
2013/06/03 PHP
php和jquery实现地图区域数据统计展示数据示例
2014/02/12 PHP
thinkphp验证码显示不出来的解决方法
2014/03/29 PHP
ThinkPHP之A方法实例讲解
2014/06/20 PHP
php实现按指定大小等比缩放生成上传图片缩略图的方法
2014/12/15 PHP
PHP获取photoshop写入图片文字信息的方法
2015/03/31 PHP
PHP中两个float(浮点数)比较实例分析
2015/09/27 PHP
PHP中strpos、strstr和stripos、stristr函数分析
2016/06/11 PHP
总结PHP如何获取当前主机、域名、网址、路径、端口和参数等
2016/09/09 PHP
PHP实现对数字分隔加千分号的方法
2019/03/18 PHP
PHP执行普通shell命令流程解析
2020/08/24 PHP
node.js中的dns.getServers方法使用说明
2014/12/08 Javascript
JavaScript中常见获取元素的方法汇总
2015/03/04 Javascript
node.js实现端口转发
2016/04/14 Javascript
AngularJS基础 ng-list 指令详解及示例代码
2016/08/02 Javascript
纯js的右下角弹窗实例
2017/03/12 Javascript
JavaScript-定时器0~9抽奖系统详解(代码)
2017/08/16 Javascript
vue动态设置img的src路径实例
2018/09/18 Javascript
微信小程序自定义底部弹出框功能
2020/11/18 Javascript
跟老齐学Python之有容乃大的list(4)
2014/09/28 Python
Mac 上切换Python多版本
2017/06/17 Python
python中的字典操作及字典函数
2018/01/03 Python
Python中的单行、多行、中文注释方法
2018/07/19 Python
解决pycharm每次新建项目都要重新安装一些第三方库的问题
2019/01/17 Python
详解Python:面向对象编程
2019/04/10 Python
Python TestCase中的断言方法介绍
2019/05/02 Python
pyqt5 禁止窗口最大化和禁止窗口拉伸的方法
2019/06/18 Python
Python3实现英文字母转换哥特式字体实例代码
2020/09/01 Python
澳洲网红粉泥面膜:Sand & Sky
2019/08/13 全球购物
金融行业务员的自我评价
2013/12/13 职场文书
六五普法规划实施方案
2014/03/21 职场文书
集中整治工作方案
2014/05/01 职场文书
项目经理任命书范本
2014/06/05 职场文书
离婚协议书格式
2015/01/26 职场文书
瘦西湖导游词
2015/02/03 职场文书
python神经网络 tf.name_scope 和 tf.variable_scope 的区别
2022/05/04 Python