iOS15 Safari打开抽屉时如何禁止body滚动并保留滚动位置
Safari 抽屉打开时禁用滚动连带且保留滚动位置方案
问题描述
页面包含可滚动内容区与不可滚动的抽屉组件:抽屉打开状态下,在页面执行上下滑动触摸操作时,Safari 地址/搜索栏会自动显示或隐藏,直接破坏布局。
- 给
body设置overflow: hidden、touch-action: none的方案在 Safari 中不生效 - 给
html标签设置overflow: hidden虽然能禁用滚动,但会导致抽屉下层的页面滚动位置直接重置到(0,0)原点
需要实现:禁用 Safari 滚动连带效果的同时,保留页面当前的滚动位置。
实现步骤
- 抽屉触发打开时,首先记录当前页面的滚动偏移量
// 存储滚动位置的变量 let cachedScrollTop = 0 // 打开抽屉逻辑内执行 cachedScrollTop = window.scrollY - 给
html、body标签同时加锁样式,配合偏移锁定视觉位置
提前定义锁滚动的CSS类:
给两个标签加上类名后,把之前记录的滚动偏移值设为根元素的负top值,避免页面跳回顶部:.scroll-lock { overflow: hidden; position: fixed; width: 100%; top: 0; left: 0; }document.documentElement.classList.add('scroll-lock') document.body.classList.add('scroll-lock') document.documentElement.style.top = `-${cachedScrollTop}px` - 抽屉关闭时,还原页面状态
移除锁滚动类,清空内联样式,再把页面滚回之前记录的位置:document.documentElement.classList.remove('scroll-lock') document.body.classList.remove('scroll-lock') document.documentElement.style.top = '' window.scrollTo(0, cachedScrollTop)
兼容性说明
- 该方案通过固定定位锁死根层,触摸滑动不会触发浏览器视口的滚动逻辑,从根源上避免Safari地址栏随滑动显隐的问题
- 如果页面存在横向滚动场景,同步记录
window.scrollX值,给根元素设置对应负left偏移,关闭时调用scrollTo传入横向偏移值即可还原 - 必须同时给
html和body加锁类,单独给其中一个标签设置在部分iOS版本中会出现视口计算错位的问题
内容的提问来源于stack exchange,提问作者Hiimdjango
相关产品推荐
相关产品推荐

