项目场景:
在写带有遮罩层的弹窗时,弹窗出现时,弹框后面的页面依然会保持滚动状态,其实这种情况并么什么影响,但是有很多时候想禁止滚动。无论在移动端还是PC端都会遇到这种情况。
在写带有遮罩层的弹窗时,弹窗出现时,页面会保持滚动状态,不符合我们的预期
看了些解决方案,大都是改变body的overflow,但是由于滚动条出现和消失,页面也会出现跳动
思路分析:
查看了很多方案,大多都是采用当弹框出现时,设置body的overflow为hidden,但是由于滚动条的出现和消失,会带动页面跟着跳动,这是不愿看到的结果。
深追下去,我们会发现,默认样式下,页面滚动条的父元素是html,而fixed的父元素是body。
第一种解决方法:在线运行
html {
width: 100%;
height: 100%;
overflow: hidden;
}
body {
width: 100%;
height: 100%;
overflow: auto;
}
完整代码:
<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出现滚动,通常设置为屏幕高度。
第二种解决方法:在线运行
.bg-container {
width: 100%;
height: 100vh;
overflow: auto;
}
完整代码:
<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>