通过js或css禁止蒙层底部页面跟随滚动:pc端推荐给body添加样式overflow: hidden;height: 100%;移动端利用移动端的touch事件,来阻止默认行为,若应用场景是全平台我们要阻止页面滚动,那么何不将其固定在视窗(即position: fixed),这样它就无法滚动了,当蒙层关闭时再释放。
场景概述
方案分析
方案一
overflow: hidden;
height: 100%;
overflow: hidden;
方案二
// node为蒙层容器dom节点
node.addEventListener('touchstart', e => {
e.preventDefault()
}, false)
<body>
<div class="page">
<!-- 这里多添加一些,直至出现滚动条 -->
<p>页面</p>
<p>页面</p>
<button class="btn">打开蒙层</button>
<p>页面</p>
</div>
<div class="container">
<div class="layer"></div>
<div class="content">
<!-- 这里多添加一些,直至出现滚动条 -->
<p>蒙层</p>
<p>蒙层</p>
<p>蒙层</p>
</div>
</div>
</body>
body {
margin: 0;
padding: 20px;
}
.btn {
border: none;
outline: none;
font-size: inherit;
border-radius: 4px;
padding: 1em;
width: 100%;
margin: 1em 0;
color: #fff;
background-color: #ff5777;
}
.container {
position: fixed;
top: 0;
left: 0;
bottom: 0;
right: 0;
z-index: 1001;
display: none;
}
.layer {
position: absolute;
top: 0;
left: 0;
bottom: 0;
right: 0;
z-index: 1;
background-color: rgba(0, 0, 0, .3);
}
.content {
position: absolute;
bottom: 0;
left: 0;
right: 0;
height: 50%;
z-index: 2;
background-color: #f6f6f6;
overflow-y: auto;
}
const btnNode = document.querySelector('.btn')
const containerNode = document.querySelector('.container')
const layerNode = document.querySelector('.layer')
const contentNode = document.querySelector('.content')
let startY = 0 // 记录开始滑动的坐标,用于判断滑动方向
let status = 0 // 0:未开始,1:已开始,2:滑动中
// 打开蒙层
btnNode.addEventListener('click', () => {
containerNode.style.display = 'block'
}, false)
// 蒙层部分始终阻止默认行为
layerNode.addEventListener('touchstart', e => {
e.preventDefault()
}, false)
// 核心部分
contentNode.addEventListener('touchstart', e => {
status = 1
startY = e.targetTouches[0].pageY
}, false)
contentNode.addEventListener('touchmove', e => {
// 判定一次就够了
if (status !== 1) return
status = 2
let t = e.target || e.srcElement
let py = e.targetTouches[0].pageY
let ch = t.clientHeight // 内容可视高度
let sh = t.scrollHeight // 内容滚动高度
let st = t.scrollTop // 当前滚动高度
// 已经到头部尽头了还要向上滑动,阻止它
if (st === 0 && startY < py) {
e.preventDefault()
}
// 已经到低部尽头了还要向下滑动,阻止它
if ((st === sh - ch) && startY > py) {
e.preventDefault()
}
}, false)
contentNode.addEventListener('touchend', e => {
status = 0
}, false)
方案三
let bodyEl = document.body
let top = 0
function stopBodyScroll (isFixed) {
if (isFixed) {
top = window.scrollY
bodyEl.style.position = 'fixed'
bodyEl.style.top = -top + 'px'
} else {
bodyEl.style.position = ''
bodyEl.style.top = ''
window.scrollTo(0, top) // 回到原先的top
}
}
思考总结
-
若应用场景是pc,推荐方案一,真的是不要太方便
-
若应用场景是h5,你可以采用方案二,但是我建议你采用方案三
-
若应用场景是全平台,那么方案三你不容错过
来源:https://segmentfault.com/a/1190000012313337