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>
相关推荐
之歆5 小时前
DAY_12JavaScript DOM 完全指南(二):实战与性能篇
开发语言·前端·javascript·ecmascript
发现一只大呆瓜5 小时前
Vite凭什么这么快?3分钟带你彻底搞懂 Vite 热更新的幕后黑手
前端·面试·vite
Maimai108086 小时前
React如何用 @microsoft/fetch-event-source 落地 SSE:比原生 EventSource 更灵活的实时推送方案
前端·javascript·react.js·microsoft·前端框架·reactjs·webassembly
kyriewen7 小时前
产品经理把PRD写成“天书”,我用AI半小时重写了一遍,他当场愣住
前端·ai编程·cursor
humcomm8 小时前
元框架的工作原理详解
前端·前端框架
canonical_entropy8 小时前
Attractor Before Harness: AI 大规模开发的方法论
前端·aigc·ai编程
zhangxingchao8 小时前
多 Agent 架构到底怎么选?从 Claude Agent Teams、Cognition/Devin 到工程落地原则
前端·人工智能·后端
IT_陈寒9 小时前
SpringBoot那个自动配置的坑,害我排查到凌晨三点
前端·人工智能·后端
Honor丶Onlyou9 小时前
VS Code 右键菜单修复记录
前端
PILIPALAPENG9 小时前
Python 语法速成指南:前端开发者视角(JS 类比版)
前端·人工智能·python