h5中弹框出现后禁止页面滚动

项目场景:

在写带有遮罩层的弹窗时,弹窗出现时,弹框后面的页面依然会保持滚动状态,其实这种情况并么什么影响,但是有很多时候想禁止滚动。无论在移动端还是PC端都会遇到这种情况。

在写带有遮罩层的弹窗时,弹窗出现时,页面会保持滚动状态,不符合我们的预期

看了些解决方案,大都是改变body的overflow,但是由于滚动条出现和消失,页面也会出现跳动

思路分析:

查看了很多方案,大多都是采用当弹框出现时,设置body的overflow为hidden,但是由于滚动条的出现和消失,会带动页面跟着跳动,这是不愿看到的结果。

深追下去,我们会发现,默认样式下,页面滚动条的父元素是html,而fixed的父元素是body。

第一种解决方法:在线运行

js 复制代码
html {
	width: 100%;
	height: 100%;
	overflow: hidden;
}
body {
	width: 100%;
	height: 100%;
	overflow: auto;
}

完整代码:

js 复制代码
<template>
  <div class="no-scroll">
    <div class="bg-container">
      <img
        src="https://img-blog.csdnimg.cn/5a87670618fe4cc59d938f77d41cb816.jpeg"
        alt=""
      />
      <img
        src="https://img-blog.csdnimg.cn/2de8a9c47e054f7ba7bd959ea5041130.jpeg"
        alt=""
      />
      <img
        src="https://img-blog.csdnimg.cn/1f4a4d8d488c46f8acad53892fed08e6.jpeg"
        alt=""
      />
      <img
        src="https://img-blog.csdnimg.cn/7b6c25d2f32645f986a26648ef0b0001.jpeg"
        alt=""
      />
      <img
        src="https://img-blog.csdnimg.cn/fbc54f7c6e2a41889d3221e1d3223127.jpeg"
        alt=""
      />
      <img
        src="https://img-blog.csdnimg.cn/d6316c5661344816bbd664a1510f9978.jpeg"
        alt=""
      />
    </div>
    <el-button class="open-btn" type="primary" round @click="open">
      打开弹框
    </el-button>
    <div class="mask-container" v-show="showMask">
      <div class="container">
        <el-button type="primary" round @click="close"> 关闭弹框 </el-button>
      </div>
    </div>
  </div>
</template>

<script>
export default {
  name: "NoScroll",
  data() {
    return {
      showMask: false,
    };
  },
  methods: {
    open() {
      this.showMask = true;
    },
    close() {
      this.showMask = false;
    },
  },
};
</script>

<style>
* {
  margin: 0;
  padding: 0;
}
html {
  width: 100%;
  height: 100%;
  overflow: hidden;
}
body {
  width: 100%;
  height: 100%;
  overflow: auto;
}
img {
  width: 100%;
}
.open-btn {
  position: fixed;
  right: 100px;
  bottom: 100px;
}
.mask-container {
  display: flex;
  align-items: center;
  justify-content: center;
  position: fixed;
  left: 0;
  top: 0;
  right: 0;
  bottom: 0;
  z-index: 10;
  background: rgba(0, 0, 0, 0.5);
}
.container {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 300px;
  height: 200px;
  background: #fff;
  border-radius: 10px;
}
</style>

如果整个架构都已经固定,担心改html、body会影响原始页面,还有另一种方案。只需要使后面滚动的容器添加一个高度就行,不让body出现滚动,通常设置为屏幕高度。

第二种解决方法:在线运行

js 复制代码
.bg-container {
  width: 100%;
  height: 100vh;
  overflow: auto;
}

完整代码:

js 复制代码
<template>
  <div class="no-scroll">
    <div class="bg-container">
      <img
        src="https://img-blog.csdnimg.cn/5a87670618fe4cc59d938f77d41cb816.jpeg"
        alt=""
      />
      <img
        src="https://img-blog.csdnimg.cn/2de8a9c47e054f7ba7bd959ea5041130.jpeg"
        alt=""
      />
      <img
        src="https://img-blog.csdnimg.cn/1f4a4d8d488c46f8acad53892fed08e6.jpeg"
        alt=""
      />
      <img
        src="https://img-blog.csdnimg.cn/7b6c25d2f32645f986a26648ef0b0001.jpeg"
        alt=""
      />
      <img
        src="https://img-blog.csdnimg.cn/fbc54f7c6e2a41889d3221e1d3223127.jpeg"
        alt=""
      />
      <img
        src="https://img-blog.csdnimg.cn/d6316c5661344816bbd664a1510f9978.jpeg"
        alt=""
      />
    </div>
    <el-button class="open-btn" type="primary" round @click="open">
      打开弹框
    </el-button>
    <div class="mask-container" v-show="showMask">
      <div class="container">
        <el-button type="primary" round @click="close"> 关闭弹框 </el-button>
      </div>
    </div>
  </div>
</template>

<script>
export default {
  name: "NoScroll",
  data() {
    return {
      showMask: false,
    };
  },
  methods: {
    open() {
      this.showMask = true;
    },
    close() {
      this.showMask = false;
    },
  },
};
</script>

<style>
* {
  margin: 0;
  padding: 0;
}
.bg-container {
  width: 100%;
  height: 100vh;
  overflow: auto;
}
img {
  width: 100%;
}
.open-btn {
  position: fixed;
  right: 100px;
  bottom: 100px;
}
.mask-container {
  display: flex;
  align-items: center;
  justify-content: center;
  position: fixed;
  left: 0;
  top: 0;
  right: 0;
  bottom: 0;
  z-index: 10;
  background: rgba(0, 0, 0, 0.5);
}
.container {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 300px;
  height: 200px;
  background: #fff;
  border-radius: 10px;
}
</style>
相关推荐
于慨21 小时前
Lambda 表达式、方法引用(Method Reference)语法
java·前端·servlet
石小石Orz21 小时前
油猴脚本实现生产环境加载本地qiankun子应用
前端·架构
从前慢丶21 小时前
前端交互规范(Web 端)
前端
CHU72903521 小时前
便捷约玩,沉浸推理:线上剧本杀APP功能版块设计详解
前端·小程序
GISer_Jing21 小时前
Page-agent MCP结构
前端·人工智能
王霸天21 小时前
💥别再抄网上的Scale缩放代码了!50行源码教你写一个永不翻车的大屏适配
前端·vue.js·数据可视化
小领航21 小时前
用 Three.js + Vue 3 打造炫酷的 3D 行政地图可视化组件
前端·github
@大迁世界21 小时前
2026年React大洗牌:React Hooks 将迎来重大升级
前端·javascript·react.js·前端框架·ecmascript
PieroPc21 小时前
一个功能强大的 Web 端标签设计和打印工具,支持服务器端直接打印到局域网打印机。Fastapi + html
前端·html·fastapi
悟空瞎说1 天前
深入 Vue3 响应式:为什么有的要加.value,有的不用?从设计到源码彻底讲透
前端·vue.js