引子
h5 页面有弹窗浮层时, 浮层之下若产生了滚动, 滑动浮层时会让其产生滚动. 这是示例页面, 移动端访问如下:
- Origin https://github.com/XXHolic/segment/issues/72
- My GitHub https://github.com/XXHolic
原因
找到的信息里面有两种说法:
使用了
-webkit-overflow-scrolling: touch
, 另外这个不是标准属性.
浮层也是页面的一个元素, 浮层的展示正常, 页面中的其它元素按照本来的方式展示运作. 也就是说这是一个正常的现象, 只不过是我们不想要这种效果.
针对第一种说法, 进行测试验证, 这是示例页面, 移动端访问如下:
发现: 跟 -webkit-overflow-scrolling: touch 无关.
处理方法
在网上找到的资料, 主要有两种思路:
阻止 touch 相关的事件.
弹出浮层时, 禁止元素滚动, 浮层消失时, 恢复滚动.
第一种思路在很多资料中提到有明显的缺陷:
弹出层的滚动会有问题.
会锁死滚动区域.
弹出层的事件处理可能会产生影响.
较多采用第二种思路, 但也有对应的问题:
元素滚动的状态切换, 会丢失滚动的位置.
针对滚动位置丢失问题, 采用动态记录滚动位置的方式可以解决.
示例代码
- // 以下方法使用的前提是产生滚动元素为 body
- function fixedEle() {
- var scrollEle = document.body;
- // 有可能出现浮层内切换的情况, 已经设置了就用重复设置了.
- if (scrollEle.style.position !== 'fixed') {
- var scrollTop = document.body.scrollTop || document.documentElement.scrollTop;
- scrollEle.style.CSSText += 'position:fixed;top:-'+scrollTop+'px;';
- }
- }
- function recoverEle() {
- var scrollEle = document.body;
- var top = scrollEle.style.top;
- scrollEle.style.position = '';
- scrollEle.style.top = '';
- document.body.scrollTop = document.documentElement.scrollTop = -parseInt(top);
- }
这是示例页面, 移动端访问如下:
参考资料
- overflow-scrolling MDN
- iOS - CSS/JS - Overlay scroll but prevent body scroll
- Prevent body scrolling on mobile device
- Prevent Page Scrolling When a Modal is Open
移动端滚动穿透问题
- GitHub body-scroll-lock https://github.com/willmcpo/body-scroll-lock
- iOS 10 Safari: Prevent scrolling behind a fixed overlay and maintain scroll position
来源: http://www.bubuko.com/infodetail-3400813.html