web页面弹出遮罩层,通过js或css禁止蒙层底部页面跟随滚动
场景概述
弹窗是一种常见的交互方式,而蒙层是弹窗必不可少的元素,用于隔断页面与弹窗区块,暂时阻断页面的交互。但是,在蒙层元素中滑动的时候,滑到内容的尽头时,再继续滑动,蒙层底部的页面会开始滚动,显然这不是我们想要的效果,因此需要阻止这种行为。
那么,如何阻止呢?请看以下分析:
方案分析
方案一
- 打开蒙层时,给body添加样式:
overflow: hidden;
height: 100%;
在某些机型下,你可能还需要给根节点添加样式:
overflow: hidden;
- 关闭蒙层时,移除以上样式。
优点:
简单方便,只需添加css样式,没有复杂的逻辑。
缺点:
兼容性不好,适用于pc,移动端就尴尬了。
部分安卓机型以及safari中,无法无法阻止底部页面滚动。
如果需要应用于移动端,那么你可能需要方案二。
方案二
就是利用移动端的touch事件,来阻止默认行为(这里可以理解为页面滚动就是默认行为)。
// node为蒙层容器dom节点
node.addEventListener('touchstart', e => {
e.preventDefault()
}, false)
办公资源网址导航 https://www.wode007.com
简单粗暴,滚动时底部页面也无法动弹了。假如你的蒙层内容不会有滚动条,那么上述方法prefect。
但是,最怕空气突然安静,假如蒙层内容有滚动条的话,那么它再也无法动弹了。因此我们需要写一些js逻辑来判断要不要阻止默认行为,复杂程度明显增加。
具体思路:判定蒙层内容是否滚动到尽头,是则阻止默认行为,反之任它横行。
touchend事件触发前),继续滑动时页面内容不会滚动,此时若松手再继续滚动,则页面内容会滚动。利用这一个小技巧,我们可以精简优化我们的代码逻辑。
Tip:这里我发现了一个小技巧,可以省略不少代码。在一次滑动中,若蒙层内容可以滚动,则蒙层内容滚动,过程中即使蒙层内容已滚至尽头,只要不松手(可以理解为
示例代码如下:
<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: ;
padding: 20px;
} .btn {
border: none;
outline: none;
font-size: inherit;
border-radius: 4px;
padding: 1em;
width: %;
margin: 1em ;
color: #fff;
background-color: #ff5777;
} .container {
position: fixed;
top: ;
left: ;
bottom: ;
right: ;
z-index: ;
display: none;
} .layer {
position: absolute;
top: ;
left: ;
bottom: ;
right: ;
z-index: ;
background-color: rgba(, , , .);
} .content {
position: absolute;
bottom: ;
left: ;
right: ;
height: %;
z-index: ;
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 = // 记录开始滑动的坐标,用于判断滑动方向
let status = // 0:未开始,1:已开始,2:滑动中 // 打开蒙层
btnNode.addEventListener('click', () => {
containerNode.style.display = 'block'
}, false) // 蒙层部分始终阻止默认行为
layerNode.addEventListener('touchstart', e => {
e.preventDefault()
}, false) // 核心部分
contentNode.addEventListener('touchstart', e => {
status =
startY = e.targetTouches[].pageY
}, false) contentNode.addEventListener('touchmove', e => {
// 判定一次就够了
if (status !== ) return status = let t = e.target || e.srcElement
let py = e.targetTouches[].pageY
let ch = t.clientHeight // 内容可视高度
let sh = t.scrollHeight // 内容滚动高度
let st = t.scrollTop // 当前滚动高度 // 已经到头部尽头了还要向上滑动,阻止它
if (st === && startY < py) {
e.preventDefault()
} // 已经到低部尽头了还要向下滑动,阻止它
if ((st === sh - ch) && startY > py) {
e.preventDefault()
}
}, false) contentNode.addEventListener('touchend', e => {
status =
}, false)
问题虽然是解决了,但是回头来看,复杂程度和代码量明显增加了一个梯度。
本着简单方便的原则,我们是不是还可以探索其他的方案呢?
既然touch事件判定比较复杂,何不跳出这个框框,另辟蹊径,探索更加合适的方案。
于是,便有了我们的方案三。
方案三
来讲讲我的思路,既然我们要阻止页面滚动,那么何不将其固定在视窗(即position: fixed),这样它就无法滚动了,当蒙层关闭时再释放。
当然还有一些细节要考虑,将页面固定视窗后,内容会回头最顶端,这里我们需要记录一下,同步top值。
示例代码:
let bodyEl = document.body
let top = 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(, top) // 回到原先的top
}
}
思考总结
- 若应用场景是pc,推荐方案一,真的是不要太方便
- 若应用场景是h5,你可以采用方案二,但是我建议你采用方案三
- 若应用场景是全平台,那么方案三你不容错过
本文到这里也即将结束了,在这里我强烈推荐一下方案三,原因在于简单、方便、兼容性好,一次封装,永久受用。
web页面弹出遮罩层,通过js或css禁止蒙层底部页面跟随滚动的更多相关文章
- 移动端和PC端弹出遮罩层后,页面禁止滚动的解决方法及探究
PC端解决方案 pc端的解决思路就是在弹出遮罩层的时候取消已经存在的滚动条,达到无法滚动的效果. 也就是说给body添加overflow:hidden属性即可,IE6.7下不会生效,需要给html增加 ...
- jquery特效(7)—弹出遮罩层且内容居中
上周写了几个小特效,其中有个点击按钮弹出遮罩层的特效,下面来看最终实现的效果: 由于是测试的程序,所以我未加关闭的按钮. 一.主体程序 <!DOCTYPE html> <html&g ...
- Css动画形式弹出遮罩层,内容区上下左右居中于不定宽高的容器中
<!DOCTYPE html> <html> <head> </head> <body id="body"> <! ...
- jQuery实现打开网页自动弹出遮罩层或点击弹出遮罩层功能示例
本文实例讲述了jQuery实现打开网页自动弹出遮罩层或点击弹出遮罩层功能.分享给大家供大家参考,具体如下: 弹出层:两种方式 一是打开网页就自动弹出层二是点击弹出 <!DOCTYPE html ...
- jQuery layer[页面弹出框]
常见接口如下: 方法名 描述 $.layer({}) 核心接口,参数是一个对象,对象属性参见上述列表.诸如layer.alert()之类的为$.layer()的包装方法. layer.v 获取版本号. ...
- layui 在页面弹出小窗口,并关闭
function showdialog() { layer.open({ type: 2, title: '发起调度', shadeClose: true, shade: 0.8, area: [ ...
- 基于jQuery向下弹出遮罩图片相册
今天给大家分享一款基于jQuery向下弹出遮罩图片相册.单击相册图片时,一个遮罩层从上到下动画出现.然后弹出显示图片.这款插件适用浏览器:IE8.360.FireFox.Chrome.Safari.O ...
- 微信内置浏览器浏览H5页面弹出的键盘遮盖文本框的解决办法(转)
最近在做微信公众号的内嵌页面,发现点击输入框时键盘盖住文本框,找到一段代码解决了这个问题. iOS和android手机都已亲测,需要的可以直接拷贝到代码中使用. js代码如下: $(function ...
- HTML页面弹出窗口调整代码总结
弹出跟你当前的窗口有没有菜单工具栏没有关系,你只要在页面中写一个脚本它就弹出了.比如<a href=# onclick="window.open('xxx.aspx','窗口名称',' ...
随机推荐
- java实现第七届蓝桥杯路径之谜
路径之谜 题目描述 小明冒充X星球的骑士,进入了一个奇怪的城堡. 城堡里边什么都没有,只有方形石头铺成的地面. 假设城堡地面是 n x n 个方格.[如图1.png]所示. 按习俗,骑士要从西北角走到 ...
- 一个Redis查询案例
1.远程登陆进服务器 使用ssh连接至Linux服务器中 2.接入redis集群 redis-cli -h 10.1.8.12 -p 29000 3.执行查询命令 根据userid查询用户的最近在线时 ...
- HashMap源码解析(java1.8.0)
1.1 背景知识 1.1.1 红黑树 二叉查找树可能因为多次插入新节点导致失去平衡,使得查找效率低,查找的复杂度甚至可能会出现线性的,为了解决因为新节点的插入而导致查找树不平衡,此时就出现了红黑树. ...
- iOS-线程&&进程的深入理解
进程基本概念 进程就是一个正在运行的一个应用程序; 每一个进度都是独立的,每一个进程均在专门且手保护的内存空间内; iOS是怎么管理自己的内存的,见博客:博客地址 在Linux系统中,想要新开启一个进 ...
- oracle使用+简写左关联出现的结果集不一致问题
这是使用(+)的sql语句(已简写) select a.id,b.num from a,b where a.id=b.id(+) and b.num>10 这是使用left join的sql语句 ...
- @atcoder - AGC029F@ Construction of a tree
目录 @description@ @solution@ @accepted code@ @details@ @description@ 给定 N - 1 个 {1, 2, ..., N} 的子集,第 ...
- Java_图片转字符
把高达头像转换成字符[-V-] 调节双循环里y与x的增量改变字符输出的细节.高和长 public class ImgToStr { public static void main(String arg ...
- position中的四种属性
Position有四个属性值,分别是static .fixed. relative .absolute. 第一个属性值是static,这是position的默认属性,一般我们都不会用到它,所以也很少提 ...
- 动态调试 别人写的jar包
在别人的jar应用程序里: 在VMoption选项中添加: -agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=50064 或者 ...
- break,continue,break的用法与区别
1.return 语句的作用 (1) return 从当前的方法中退出,返回到该调用的方法的语句处,继续执行. (2) return 返回一个值给调用该方法的语句,返回值的数据类型必须与方 ...