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>
相关推荐
剪刀石头布啊2 小时前
javascript手动实现继承
前端
Elias不吃糖3 小时前
Langfuse 入门:Trace、Prompt、Dataset、Experiment、Evaluator
前端·python·prompt·langfuse
vipbic3 小时前
一个前端的 9 天重构:我是怎么用 Codex 重做航栈的
前端·javascript·后端
Eason_Lou4 小时前
【无标题】
前端·vue.js·html
_codemonster5 小时前
npm run dev 是在开发模式运行,怎么在生产环境运行
前端·npm·node.js
kyriewen5 小时前
我受够了复制报错去问 AI,花一下午给控制台做了个调试助手
前端·javascript·ai编程
IT_陈寒6 小时前
Redis的DEL命令竟然没删掉数据?我踩的这个坑你得知道
前端·人工智能·后端
anOnion6 小时前
构建无障碍组件之Menu and Menubar Pattern
前端·html·交互设计
JavaGuide6 小时前
我用 Claude Code/ZCode+GLM-5.3 从零做了一款 Agent 游戏!
前端·后端