css遮罩层-移动端开发遮罩层(弹窗)防止滚动穿透解决方案

在移动页面开发中,经常需要封装一个描边层(全屏弹窗)、遮罩层(全屏弹窗)、遮罩层(全屏弹窗)组件,但如果是固定定位位置:fixed ; 弹出来的时候会遇到一些小坑。 之前搜了一下,无论是网上博客还是评论,总有一些缺陷或者代码太多遮挡眼睛。 比如明天的主题,如何防止描边层下面的正文内容(全屏弹窗)继续滚动?

移动端开发遮罩层(弹窗)防止滚动穿透的完美解决方案

首先PC端必须直接给body设置一个overflow:hidden属性,这是一个完美的解决方案。

这个没什么好说的css遮罩层,主要是在手机上,大家会发现给body添加的属性根本没有效果,还有遮罩层的时候怎么滑动或者怎么滑动(全屏弹窗)出现。

下面给出三种解决方案:

第一种解决方案(参考别人的解决方案):

点击弹出的时候,给html和body都添加overflow:hidden属性。 这时候你会发现背景不再滚动了,但是这样做有一个隐忧,那就是当遮罩层(全屏弹窗)消失的时候,页面会被手动返回至底部。 当有人浏览页面时,点击弹窗后消失然后返回底部? 显然不合理。 所以当你点击消失的时候,你得记录下当前的scrollTop,然后把形参给当前页面的scroll,就算解决了。 这里就不详细介绍写法了。 我推荐一个github作者来介绍这些技巧。 点击查看>>

ps:我个人认为这些方法也可以,但是代码太多,那就看下面的解决办法

第二种解决方案(适用于简单的弹窗):

直接在遮罩层(弹窗)上添加@touchmove.prevent(这里是vue中),它的作用是当你抚摸全屏层(弹窗)时,严禁滑动,原理是因为弹出层的滑动是严格禁止的。 自然就不存在滑动穿透的问题了。 是不是很简单粗暴呢? 我们想要做得更好的是给body添加一个overflow:hidden属性,这样人为的自动滑动就无法意外,也无法执行其他工具的滑动(鼠标)

document.body.classList.add('overflow-hidden');

.overflow-hidden{
    overflow: hidden;
}
.box{
    width: 100%;
    height:100%;
    position: fixed;
    top: 0;
    background: rgba(0,0,0,0.8);
}

第三种方案(适合封装组件,弹出时可以控制内容区域滚动的复杂情况):

点击弹窗时css遮罩层,监控touchmove风暴,严格禁止。

层遮罩和层颜色的区别_css遮罩层

当点击消失时,听同样的风暴,删除删除。

这样做的用处在于,滑动风暴并不是在结构中直接禁用,而是通过指令控制,更适合开发需要。

click(){//点击弹窗
    this.tan=true
    document.body.classList.add('overflow-hidden');
    document.addEventListener('touchmove', this.touchStart,{passive:false});//一般第三个参数可直接填false,true -> 表示在捕获阶段调用事件处理程序, false -> 表示在冒泡阶段调用事件处理程序使用,但是touchmove会被浏览器忽略掉,并不会阻止默认行为,这里通过passive:false明确声明为不是被动的
},
touchStart(){
    event.preventDefault();//通知 Web 浏览器不要执行与事件关联的默认动作
},
close(){//点击关闭弹窗
    this.tan=false
    document.body.classList.remove('overflow-hidden');
    document.removeEventListener('touchmove',this.touchStart,{passive:false});
}

你学会了吗? 帮您点赞加关注,有不懂或者不懂的欢迎留言。

最近在项目开发中遇到一个需求:页面左右布局分割线css,需要拖拽分割线实现手动适配长度。

解决方案

一般来说,在mounted生命周期中,监听分割线DOM的onmousedown,在拖拽过程中动态估计分割线css,然后用形参改变左右DOM元素的长度,就完成了。

模板部分:类为“touch-div”,即DOM的分割线。

<template>
  <div class="wrap">
    <div class="lf" ref="letfDom" style="width: 280px;">
      <router-link to="/moreClick">moreClick</router-link>
      <div class="touch-div" ref="moveDom">
        <span></span>
        <span></span>
      </div>
    </div>
    <div class="rt">
      <router-view />
    </div>
  </div>
</template>

CSS部分:cursor:col-resize; 可以实现键盘悬停时的左右箭头。

.wrap .lf .touch-div {
  position: absolute;
  top: 0;
  height: 100%;
  left: 100%;
  width: 20px;
  display: flex;
  justify-content: center;
  align-items: center;
  cursor: col-resize;
}
.wrap .lf .touch-div span {
  width: 2px;
  background: #bbb;
  margin: 0 2px;
  height: 15px;
}

JavaScript部分

export default {
  name: "App",
  data() {
    return {
      letfDom: null,
      clientStartX: 0
    };
  },
  mounted() {
    this.letfDom = this.$refs.letfDom;
    let moveDom = this.$refs.moveDom;
    moveDom.onmousedown = e => {
      this.clientStartX = e.clientX;
      e.preventDefault();
      document.onmousemove = e => {
        this.moveHandle(e.clientX, this.letfDom);
      };
      document.onmouseup = e => {
        document.onmouseup = null;
        document.onmousemove = null;
      };
    };
  },
  methods: {
    moveHandle(nowClientX, letfDom) {
      let computedX = nowClientX - this.clientStartX;
      let leftBoxWidth = parseInt(letfDom.style.width);
      let changeWidth = leftBoxWidth + computedX;
      if (changeWidth < 280) {
        changeWidth = 280;
      }
      if (changeWidth > 400) {
        changeWidth = 400;
      }
      letfDom.style.width = changeWidth + "px";
      this.clientStartX = nowClientX;
    }
  }
};

示例代码下载

您可以复制上面的代码并运行看看疗效,也可以去GitHub:下载,更多示例将持续更新,欢迎关注。