vue添加全屏遮罩,并且消除滚动条

Posted yoxixi

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了vue添加全屏遮罩,并且消除滚动条相关的知识,希望对你有一定的参考价值。

今天做移动端菜单适配,小屏幕时利用媒体查询,将菜单缩成一个icon,点击icon弹出侧边栏菜单

技术分享图片

先添加一个遮罩层,然后添加菜单,菜单的zindex高于遮罩层,菜单icon的zindex高于菜单,定位固定在右上角,这样点击icon菜单滑进滑出,icon的位置不需要额外调整。

//菜单icon
.navbar-icon {
   width: 30px;
   display: none;
   position: absolute;
   top: 20px;
   right: 20px;
   z-index: 101;
   cursor: pointer;
 }
  //菜单列表弹层
  .navbar-phone{
  position: fixed;
  top: 0;
  left: 0;
  right: 0;
  bottom: 0;
  z-index: 100;
  font-size: 14px;
  background-color: #fff;
  overflow: hidden;
  -webkit-transform: translateX(40%);
  transform: translateX(40%);
}
//半透明遮罩
.shadePage{
  width: 100%;
  background: #ddd;
  position: fixed;
  top: 0;
  right: 0;
  left: 0;
  bottom: 0;
  opacity: 0.7;
  z-index: 99;
}

基本功能做好了,但是发现弹出菜单页后,整个遮罩和菜单内容是可以随下面的页面滚动的,这显然是不符合我们需求的,原本的思路是让这个遮罩层的高度只等于屏幕高度,于是在这个坑上最走越远,查了不少资料,有的是用js动态算出屏幕高度赋值给遮罩的,有说给html,body所有父容器增加height:100%,然后容器height:100%的,但是即使遮罩高度固定,屏幕仍然可以滚动。这时候发现让遮罩充满整个屏幕的思路是错的,于是搜到了遮罩层去除滚动的。

因为项目引用了elementUI,有人说可以直接调用element提供的loading组件,调用了下,loading组件确实可以整个屏幕全屏,无滚动,但是有两个痛点,一个是有一个一直存在的loading动画,一个是遮罩的zindex是根据当前容器里元素最高的zindex动态生成的,本来遮罩的zindex是2000,我想让弹出层盖在遮罩上,设置了zindex:2004,结果页面上遮罩的zindex变成了2005。看来eleme的loading主要是用于页面过渡的,不大适合做通用的遮罩。

还有通过js阻止浏览器默认事件的,但是这样一棒子打死,弹出层若想添加滚动的内容就实现不了了。

这时候找到一篇最完美的解决方案,点击弹出的时候,给body添加overflow:hidden的样式,关闭遮罩的时候重新打开,同时打开的时候记录下当前页面滚动的位置,关闭的时候需要回归当前位置。

全局添加样式:

body.dialog-open {
  position: fixed;
  width: 100%;
}

添加全局方法:

  const ModalHelper = ( (bodyCls) =>{
    let scrollTop;
    return {
      afterOpen: function () {
          scrollTop = document.scrollingElement.scrollTop;
          document.body.classList.add(bodyCls);
          document.body.style.top = -scrollTop + ‘px‘;
      },
      beforeClose: function () {
          document.body.classList.remove(bodyCls);
          // scrollTop lost after set position:fixed, restore it back.
          document.scrollingElement.scrollTop = scrollTop;
      }
    };
  })(‘dialog-open‘); 

然后监听一下控制弹出层显示的变量,调用添加和消除样式:

   watch: {
      phoneMenu:function(val) {
        if (!!val){
          ModalHelper.afterOpen();
        } else {
          ModalHelper.beforeClose();
        }
      }
    }

大功告成

 

以上是关于vue添加全屏遮罩,并且消除滚动条的主要内容,如果未能解决你的问题,请参考以下文章

jQuery10种不同动画效果的响应式全屏遮罩层

页面弹出全屏浮层或遮罩时,禁止底层body滚动

覆盖javascript以消除闪烁

JS简易弹出层

[Vue Js]如何实现一个带遮罩的全屏div

JS弹出层遮罩,隐藏背景页面滚动条细节优化