顶部固定不动 下部分滚动_如何彻底解决背景跟随弹窗滚动问题

背景

在移动端使用弹窗时,我们会经常遇到这种现象:滑动弹窗时,遮罩层下面的背景(body)也会跟随滑动,带来的用户观感体验很差。

市面上的解决方案大部分通过阻止touchmove默认事件执行event.preventDefault()解决,但是这种方案存在兼容性,不能对所有浏览器都有效,而且如果弹窗本身存在滚动(如活动规则弹窗),这种解决方案并不能阻止背景滑动,如下图活动规则弹窗所示:

aa144d83863dbde10f9d42f093efc619.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停留在原来的浏览位置,而不是自动滚动到顶部。

明确了要达到的目的,就很好解决了。

  1. body设置fixed样式之前,先记录下滚动条的偏移位置。

let top = document.body.scrollTop || document.documentElement.scrollTop;
  1. body设置fixed样式后,页面会滚动到顶部,我们通过设置top,让body偏移到原来的浏览位置就可以了。注意,这里的top要设置为负数。

document.body.style.top = `${-1 * top}px`;
  1. 关闭弹窗,恢复页面滚动,基本上是一个逆向思路。恢复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%
}

总结

该方案基本上能够完美解决我们移动端遇到的背景滚动问题,对短弹窗和长弹窗(弹窗自身有内容滚动)都适用,不存在兼容性问题。我在做活动页的过程中,都是用的这个方法,实践证明是可靠的,放心使用。

10696e97734d300b4af639cf3dcf975a.png

 相关推荐前端面试128问汇总(含超详细答案)如何和面试官吹嘘一下我的Vue项目性能优化

「面试必问」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面试题!面试官再也难不到你了!

d169e7a7cb118020a678a8c567bb664f.png

a30d3a549f986e7e734cdfbc49568c2c.png点在看的人特别帅/美 9fb86ce162f8cd2e3bc53e9caeed86d3.gif
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值