开发过程中经常使用遮罩层展示重要信息,同时屏蔽对下层页面的操作,其中一个可以提升用户体验感的地方就是点击非内容区域关闭遮罩层,本文就提供三种思路,四种实现方案。

其中遮罩层样式如下:

<style lang="less" scoped>
.maskParent {
  width: 100%;
  height: 100%;
  position: absolute;
  left: 0;
  top: 0;
  z-index: 998;
  background-color: #000;
  opacity: 0.6;
}

一、父节点为遮罩层,子节点为内容(事件委托)

<div class="maskParent">  
 <div>内容</div>
</div>

事件委托有两种实现方案

第一种,利用event对象的target属性判断点击事件是否为遮罩层

<div class="maskParent" @click="handler">
  <div>内容</div>
</div>
<script>
function handler(event) {
  if (event.target === '父节点') {
    this.visible = false // 关闭遮罩层
  }
}
</script>

第二种,阻止内容区域click的事件冒泡

<div class="maskParent" @click="maskHandler">
  <div @click="handler">内容</div>
</div>
<script>
function handler(event) {
  event.stopPropagation()
  event.cancelBubble = true
}
function maskHandler() {
  this.visible = false
}

二、遮罩层和内容是兄弟节点,直接在遮罩层绑定click事件

<div class="maskParent" @click="maskHandler"></div>
<div @click="handler">内容</div>
<script>
function handler(event) {
  this.visible = false // 关闭遮罩层
}
</script>

下面是最佳实践:

<div clas="dialog">
	<div id="dialog__mask"></div>
	<div class="dialog__cotent"></div>
	</div>
</div>
.dialog {
  display: none;
  position: fixed;
  left: 0;
  right: 0;
  top: 0;
  bottom: 0;
  z-index: 1000;
  &__mask {
    position: absolute;
    left: 0;
    right: 0;
    top: 0;
    bottom: 0;
    top: 0;
    background-color: rgba(0,0,0,0.3);
  }
 
  &.show {
    &__content  {
      display: flex;
      animation:
        fadeIn 0.5s,
        slideInRight 0.5s;
    }
  }
 
  &.hide {
    &__content  {
      animation: slideOutRight 0.5s;
    }
  }
 
  .__content {
    position: absolute;
    right: 0;
    top: 0;
    bottom: 0;
    width: 509px;
  }
}

三、死脑筋操作(不受节点限制)

根据鼠标点击坐标(clientX,clientY)判断是不是遮罩层非内容区域,感觉没人会用,拍脑袋想到的方法。