蝙蝠岛资源网 Design By www.hbtsch.com

原始实现

下面是两种常见的模态框的实现方式

方案一:默认 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的资料请关注其它相关文章!

标签:
Vue,OutClick,Vue,Click

蝙蝠岛资源网 Design By www.hbtsch.com
广告合作:本站广告合作请联系QQ:858582 申请时备注:广告合作(否则不回)
免责声明:本站文章均来自网站采集或用户投稿,网站不提供任何软件下载或自行开发的软件! 如有用户或公司发现本站内容信息存在侵权行为,请邮件告知! 858582#qq.com
蝙蝠岛资源网 Design By www.hbtsch.com

评论“Vue指令实现OutClick的示例”

暂无Vue指令实现OutClick的示例的评论...

《魔兽世界》大逃杀!60人新游玩模式《强袭风暴》3月21日上线

暴雪近日发布了《魔兽世界》10.2.6 更新内容,新游玩模式《强袭风暴》即将于3月21 日在亚服上线,届时玩家将前往阿拉希高地展开一场 60 人大逃杀对战。

艾泽拉斯的冒险者已经征服了艾泽拉斯的大地及遥远的彼岸。他们在对抗世界上最致命的敌人时展现出过人的手腕,并且成功阻止终结宇宙等级的威胁。当他们在为即将于《魔兽世界》资料片《地心之战》中来袭的萨拉塔斯势力做战斗准备时,他们还需要在熟悉的阿拉希高地面对一个全新的敌人──那就是彼此。在《巨龙崛起》10.2.6 更新的《强袭风暴》中,玩家将会进入一个全新的海盗主题大逃杀式限时活动,其中包含极高的风险和史诗级的奖励。

《强袭风暴》不是普通的战场,作为一个独立于主游戏之外的活动,玩家可以用大逃杀的风格来体验《魔兽世界》,不分职业、不分装备(除了你在赛局中捡到的),光是技巧和战略的强弱之分就能决定出谁才是能坚持到最后的赢家。本次活动将会开放单人和双人模式,玩家在加入海盗主题的预赛大厅区域前,可以从强袭风暴角色画面新增好友。游玩游戏将可以累计名望轨迹,《巨龙崛起》和《魔兽世界:巫妖王之怒 经典版》的玩家都可以获得奖励。