滚动穿透处理方案
之前看到过一些关于滚动穿透和点击穿透的文章,一般滚动穿透会比较常见,但是点击穿透却不怎么常见。之前的产品也没有要求过处理滚动穿透,所以也就没怎么处理过。
先说下业务场景:当前浏览的页面很长,是可以滚动的。页面上会出现弹框,弹框还可以滚动,这个时候就会有滚动穿透的问题了。
网上找到了一个思路特别简单的方法:弹窗打开的时候,给body设置 position: fixed;width: 100%;top: 0px;
,让body脱离文档流,这个时候页面就不能滚动,按时弹窗还是可以滚动的。等弹窗关闭的时候,再把body设置恢复就行了。
贴上一个demo:如下。由于页面中遇到了3,4个遮罩层。所以就没有给每个click去添加,而且监测遮罩层的打开关闭——即变量layerShow。layerShow等于true即遮罩被打开的时候,获取dom的scrollTop,然后设置body的样式为position: fixed;width: 100%;top: ${-this.sctop}px;
。当layerShow等于false即遮罩被关闭的时候,设置body样式恢复原状,然后让页面滚动到原来的位置window.scrollTo(0, this.sctop)
<template>
<div id="blackbox" v-show="layerShow" class="layer">
<div @click="closeLayer" class="layer-bg"></div>
<div class="slot-wrapper">
<slot></slot>
</div>
</div>
</template>
<script>
export default {
data() {
return {
sctop: 0
};
},
props: {
layerShow: {
type: Boolean,
default: false
}
},
watch: {
layerShowValue(newValue, oldValue) {
if(newValue) {
this.sctop = document.body.scrollTop || document.documentElement.scrollTop
document.body.style.cssText = `position: fixed;width: 100%;top: ${-this
.sctop}px;`;
} else {
document.body.style.cssText = "";
window.scrollTo(0, this.sctop);
}
}
},
computed: {
layerShowValue() {
return this.layerShow;
}
},
methods: {
closeLayer() {
this.$emit("closeLayer");
}
}
};
</script>
<style lang='scss' scoped>
.layer {
position: fixed;
top: 0;
left: 0;
width: 750px;
height: 100vh;
.layer-bg {
background: #000;
opacity: 0.5;
width: 100%;
height: 100%;
}
.slot-wrapper {
position: absolute;
top: 0;
left: 0;
}
}
</style>