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添加String.Format方法
Aug 11 Javascript
把字符串按照特定的字母顺序进行排序的js代码
Jan 28 Javascript
Javascript中innerHTML用法实例分析
Jan 12 Javascript
简介JavaScript中的italics()方法的使用
Jun 08 Javascript
Javascript中常见的逻辑题和解决方法
Sep 17 Javascript
jQuery无缝轮播图代码
Dec 22 Javascript
ES6教程之for循环和Map,Set用法分析
Apr 10 Javascript
解决JS外部文件中文注释出现乱码问题
Jul 09 Javascript
深入解析vue 源码目录及构建过程分析
Apr 24 Javascript
vue-next/runtime-core 源码阅读指南详解
Oct 25 Javascript
详解JavaScript类型判断的四种方法
Oct 21 Javascript
微信小程序:报错(in promise) MiniProgramError
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获取linux服务器状态的代码
2014/05/27 PHP
php实现的替换敏感字符串类实例
2014/09/22 PHP
PHP反射API示例分享
2016/10/08 PHP
PHP使用两个栈实现队列功能的方法
2018/01/15 PHP
使用typeof方法判断undefined类型
2014/09/09 Javascript
高性能JavaScript DOM编程(1)
2015/08/11 Javascript
jquery实现可自动判断位置的弹出层效果代码
2015/10/12 Javascript
Zero Clipboard实现浏览器复制到剪贴板的方法(多个复制按钮)
2016/03/24 Javascript
jQuery基础知识点总结(必看)
2016/05/31 Javascript
jQuery中 $ 符号的冲突问题及解决方案
2016/11/04 Javascript
angular+ionic 的app上拉加载更新数据实现方法
2017/01/16 Javascript
详解webpack介绍&amp;安装&amp;常用命令
2017/06/29 Javascript
深入浅析AngularJs模版与v-bind
2018/07/06 Javascript
JS实现的获取银行卡号归属地及银行卡类型操作示例
2019/01/08 Javascript
解决Idea、WebStorm下使用Vue cli脚手架项目无法使用Webpack别名的问题
2019/10/11 Javascript
简单了解常用的JavaScript 库
2020/07/16 Javascript
原生js+canvas实现下雪效果
2020/08/02 Javascript
python字符串排序方法
2014/08/29 Python
Python获取系统默认字符编码的方法
2015/06/04 Python
单链表反转python实现代码示例
2018/02/08 Python
python简单实现AES加密和解密
2019/03/28 Python
Jacobi迭代算法的Python实现详解
2019/06/29 Python
Python几种常见算法汇总
2020/06/02 Python
Python3+selenium配置常见报错解决方案
2020/08/28 Python
html5+css3气泡组件的实现
2014/11/21 HTML / CSS
STP的判定过程
2012/10/01 面试题
口头翻译求职人自荐信
2013/12/07 职场文书
可口可乐广告词
2014/03/20 职场文书
法院授权委托书格式
2014/09/28 职场文书
三方股东合作协议书范本
2014/09/28 职场文书
场地使用证明模板
2014/10/25 职场文书
费城故事观后感
2015/06/10 职场文书
CSS3实现的文字弹出特效
2021/04/16 HTML / CSS
Mysql文件存储图文详解
2021/06/01 MySQL
浅谈JavaScript作用域
2021/12/06 Javascript
virtualenv隔离Python环境的问题解析
2022/06/21 Python