背景
在移动端使用弹窗时,我们会经常遇到这种现象:滑动弹窗时,遮罩层下面的背景(body)也会跟随滑动,带来的用户观感体验很差。
市面上的解决方案大部分通过阻止touchmove
默认事件执行event.preventDefault()
解决,但是这种方案存在兼容性,不能对所有浏览器都有效,而且如果弹窗本身存在滚动(如活动规则弹窗),这种解决方案并不能阻止背景滑动,如下图活动规则弹窗所示:
![aa144d83863dbde10f9d42f093efc619.gif](https://i-blog.csdnimg.cn/blog_migrate/9eaf0d388b2225cdb8596e8c132641f7.gif)
终极解决方案
先上代码,超级简短
// 展示弹窗时,阻止背景滚动
function stopScroll () {
let top = document.body.scrollTop || document.documentElement.scrollTop;
document.body.style.position = 'fixed';
document.body.style.top = `${-1 * top}px`;
}
// 隐藏弹窗时,恢复背景的滚动
function recoverScroll () {
let top = -parseInt(document.body.style.top);
document.body.style.position = 'static';
document.body.style.top = 0;
window.scrollTo(0, top);
}
// 注意事项
// 设置fixed后页面元素会发生偏移,通过设置body样式可以解决这个问题
body {
width: 100%;
}
下面我们分析下原理:
该方案主要是利用position: fixed
特性,展示弹窗时给body
设置该样式,就能阻止body的滚动。
但是body
设置fixed
样式后会导致页面自动滚动到顶部,不会固定在原来的浏览位置,导致关闭弹窗后,还要从头滚动页面继续浏览,用户体验不好。
所以,我们最终要解决的问题就转化为:body设置fixed样式后,让body停留在原来的浏览位置,而不是自动滚动到顶部。
明确了要达到的目的,就很好解决了。
在
body
设置fixed
样式之前,先记录下滚动条的偏移位置。
let top = document.body.scrollTop || document.documentElement.scrollTop;
body
设置fixed
样式后,页面会滚动到顶部,我们通过设置top
,让body
偏移到原来的浏览位置就可以了。注意,这里的top要设置为负数。
document.body.style.top = `${-1 * top}px`;
关闭弹窗,恢复页面滚动,基本上是一个逆向思路。恢复
body
默认的top、position样式,把页面滚动到原来的偏移位置。
let top = -parseInt(document.body.style.top);
document.body.style.position = 'static';
document.body.style.top = 0;
window.scrollTo(0, top);
注意事项
在设置body为fixed后,有些页面元素会发生偏移,我们给body加个宽度限制就可以解决这类问题了
body {
width: 100%
}
总结
该方案基本上能够完美解决我们移动端遇到的背景滚动问题,对短弹窗和长弹窗(弹窗自身有内容滚动)都适用,不存在兼容性问题。我在做活动页的过程中,都是用的这个方法,实践证明是可靠的,放心使用。
「面试必问」leetcode高频题精选
经常需要谷哥的ccs问题完美方案汇总
【面试准备】每日前端面试题 - 41 (react篇)
【面试准备】每日前端面试题 - 40 (VUE篇)
【面试准备】每日前端面试题 - 39 (js篇)【面试准备】每日前端面试题 - 38 (CSS篇)
【面试准备】每日前端面试题 - 37【面试准备】每日前端面试题 - 36
【面试准备】每日前端面试题 - 35 【面试准备】每日前端面试题 - 34【面试准备】每日前端面试题 - 33(头条面试题)
【面试准备】每日前端面试题 - 33【面试准备】每日前端面试题 - 32
【面试准备】每日前端面试题 - 31【面试准备】每日前端面试题 - 30【面试准备】每日前端面试题 - 29 (头条面试题)【面试准备】每日前端面试题 - 28 (常考题型)【面试准备】每日前端面试题 - 27【面试准备】每日前端面试题 - 26【面试准备】每日前端面试题 - 25(头条试题)【面试准备】每日前端面试题 - 24(腾讯面试题))
【面试准备】每日前端面试题 - 23【面试准备】每日前端面试题 - 22 (头条笔试题)
【面试准备】每日前端面试题 - 21 (贝壳笔试题)
【面试准备】每日前端面试题 - 20【面试准备】每日前端面试题 - 19
【面试准备】每日前端面试题 - 18
【面试准备】每日前端面试题 - 17
【面试准备】每日10道前端面试题 - 16
【面试准备】每日10道前端面试题 - 15
【面试准备】每日10道前端面试题 - 14
【面试准备】每日10道前端面试题 - 13
【面试准备】每日10道前端面试题 - 12
【面试准备】每日10道前端面试题 - 11
【面试准备】每日10道前端面试题 - 10
【面试准备】每日10道前端面试题 - 09
【面试准备】每日10道前端面试题 - 08
【面试准备】每日10道前端面试题 - 07
【面试准备】每日10道前端面试题 - 06
【面试准备】每日10道前端面试题 - 05
【面试准备】每日10道前端面试题 - 04
【面试准备】每日10道前端面试题 - 03
【面试准备】每日10道前端面试题 - 02
【面试准备】每日10道前端面试题 - 01
移动端1px问题应该如何解决?
为什么我们要熟悉这些通信协议?【精读】
前端面向对象,高阶JS应用!
面试前必读!!!原生JS补给(上)
前端p6笔试题,你可以答上多少个?
每天都在用class,你到底对它了解多小?
前端工程师必须掌握的几个JavaScript设计模式及场景应用
【JS进阶深挖】完全弄懂数据类型转换(下)
【收藏系列】JS灵魂之问(下) - 附个人成长经验分享
【收藏系列】JS灵魂之问, 是否有offer看你接到多少个(中)
【收藏系列】JS灵魂之问, 请问你能接得住几个?(上)
【大厂面试】20道超高频题目 【JS进阶深挖】完全弄懂数据类型转换(上) 前端架构师最终面试题!48道题JS继承题目【面试官再也难不倒你了系列】神奇的arguments笔试题【一天突破一个知识点】45道Promise面试题【面试官再也难不倒你了系列】40道this面试题!面试官再也难不到你了!![a30d3a549f986e7e734cdfbc49568c2c.png](https://i-blog.csdnimg.cn/blog_migrate/68aaaf4def35d72b14133ca404e17f0d.png)
![9fb86ce162f8cd2e3bc53e9caeed86d3.gif](https://i-blog.csdnimg.cn/blog_migrate/1675ba61aa86263d1e79068d143937b8.gif)