10

习惯性记录日常工作所遇坑点,不仅仅是经验分享,真心希望走过路过的大神留言赐教!

场景如述:蒙层下一可滚动加载的 List,蒙层上一可滚动加载的 List。

目标为蒙层展现时下层滚动不触发,几种解决方案:

  • 禁用下层 touch 事件
  • 禁用下层滚动事件
  • 裁切下层溢出屏幕元素曲线禁用下层滚动事件

禁用 touch 事件,你可分别禁用 touchstart、touchmove、touchend,也可巧妙的为元素设置 touch-action: none 属性。但滚动滑块依然存在:

用户无法触摸触发滚动但可拖动滑块触发滚动...

于是乎将下层元素裁切至与屏幕等高,无溢出自然不会触发滚动,裁切方案如下:

  • 蒙层呈现时设置下层元素高度为屏幕可用高度,并添加 overflow: hidden 属性;蒙层消失时恢复元素默认设置。
  • 蒙层呈现时为下层元素添加 fixed 定位属性;蒙层消失时恢复元素默认设置。
{
    position: fixed;
    top: 0;
    left: 0;
    width: 100%;
    height: 100%;
    overflow: hidden;
}

方案二显然优于方案一,因未动用 JS 且考虑大多人区分不清 availHeight、clientHeight、offsetHeight、scrollHeight...

但蒙层消失时下层的 scrollTop 未恢复...

假定下层 List 含 100 条数据,用户滚动浏览至第 60 ~ 70 条这一屏时开启蒙层,下层元素被裁切默默恢复 scrollTop = 0。蒙层关闭时将为用户呈现第 0 ~ 10 条数据而非第 60 ~ 70 条,用户想继续浏览第 70 ~ 100 条则需疯狂上拉页面。

故在开启蒙层前记录此刻 scrollTop 值,关闭蒙层时恢复下层 scrollTop。然 scrollTop 的获取与设置依然有坑,存在以下两种方式:

  • document.documentElement.scrollTop
var scrollTop = document.documentElement.scrollTop
document.documentElement.scrollTop = scrollTop
  • document.body.scrollTop
var scrollTop = document.body.scrollTop
document.body.scrollTop = scrollTop

部分浏览器支持 document.documentElement.scrollTop 而部分支持 document.body.scrollTop,所幸其中一者有值另一者必为 0,取巧方案:

var scrollTop = document.documentElement.scrollTop + document.body.scrollTop
document.documentElement.scrollTop = scrollTop
document.body.scrollTop = scrollTop

不幸的是,即便裁切元素可防止触摸蒙层时下层滚动,但滚动事件依然透至下层,导致上层滚动卡涩。IOS 如是,Android 经住了考验(Android 终于胜出一局)。

上述方案有缺陷,希望走过路过的大神留言赐教!


作者:呆恋小喵

我的后花园:https://sunmengyuan.github.io...

我的 github:https://github.com/sunmengyuan

原文链接:https://sunmengyuan.github.io...


呆恋小喵
745 声望42 粉丝

本人女,前端打酱油一枚。2015 年毕业于中国传媒大学数字媒体技术专业。爱好:逛街、淘宝、学习;专长:数学、绘画、卖萌。