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 相关文章推荐
再谈IE中Flash控件的自动激活 ObjectWrap
Mar 09 Javascript
jQuery EasyUI API 中文文档 - Dialog对话框
Nov 15 Javascript
jQuery cdn使用介绍
May 08 Javascript
jquery之超简单的div显示和隐藏特效demo(分享)
Jul 09 Javascript
javascript实现促销倒计时+fixed固定在底部
Sep 18 Javascript
原生javascript实现addClass,removeClass,hasClass函数
Feb 25 Javascript
jQuery基于toggle实现click触发DIV的显示与隐藏问题分析
Jun 12 Javascript
RequireJs的使用详解
Feb 19 Javascript
vuejs手把手教你写一个完整的购物车实例代码
Jul 06 Javascript
vue实现滑动切换效果(仅在手机模式下可用)
Jun 29 Javascript
javascript简单实现深浅拷贝过程详解
Oct 08 Javascript
解决vue语法会有延迟加载显现{{xxx}}的问题
Nov 14 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通过COM使用ADODB的简单例子
2006/12/31 PHP
非常重要的php正则表达式详解
2016/01/04 PHP
php打乱数组二维数组多维数组的简单实例
2016/06/17 PHP
PHP中trait使用方法详细介绍
2017/05/21 PHP
php使用 readfile() 函数设置文件大小大小的方法
2017/08/11 PHP
PHP中define() 与 const定义常量的区别详解
2019/06/25 PHP
bgsound 背景音乐 的一些常用方法及特殊用法小结
2010/05/11 Javascript
根据对象的某一属性进行排序的js代码(如:name,age)
2010/08/10 Javascript
浅析jQuery中常用的元素查找方法总结
2013/07/04 Javascript
jQuery实现模拟marquee标签效果
2015/07/14 Javascript
VueAwesomeSwiper在VUE中的使用以及遇到的一些问题
2018/01/11 Javascript
使用 vue.js 构建大型单页应用
2018/02/10 Javascript
30分钟快速入门掌握ES6/ES2015的核心内容(上)
2018/04/18 Javascript
JS实现可用滑块滑动的缓动图代码
2019/09/01 Javascript
详解Vue中CSS样式穿透问题
2019/09/12 Javascript
[16:56]教你分分钟做大人:司夜刺客
2014/10/30 DOTA
Python内置函数—vars的具体使用方法
2017/12/04 Python
python爬虫基本知识
2018/03/05 Python
python 图像平移和旋转的实例
2019/01/10 Python
pybind11在Windows下的使用教程
2019/07/04 Python
Python如何优雅获取本机IP方法
2019/11/10 Python
Keras 中Leaky ReLU等高级激活函数的用法
2020/07/05 Python
Django如何在不停机的情况下创建索引
2020/08/02 Python
Python3读写ini配置文件的示例
2020/11/06 Python
谈谈对css属性box-sizing的了解
2017/01/04 HTML / CSS
公司道歉信范文
2014/01/09 职场文书
业务员薪酬管理制度
2014/01/15 职场文书
十岁生日父母答谢词
2014/01/18 职场文书
前台文员职责范本
2014/03/07 职场文书
欢迎标语大全
2014/06/21 职场文书
乡镇安全生产目标责任书
2014/07/23 职场文书
地方白酒代理协议书
2014/10/25 职场文书
毕业论文答辩演讲稿
2015/06/23 职场文书
劳保用品管理制度范本
2015/08/06 职场文书
详解Flutter自定义应用程序内键盘的实现方法
2022/06/14 Java/Android
spring boot实现文件上传
2022/08/14 Java/Android