最近在做新版主题开发的时候遇到了糟心的问题,就是当左侧的侧滑式菜单弹出展开时,在屏幕上滑动菜单的内容,底部的内容也会跟着一起滑动,这个体验很不友好,其实已经通过 JS 对触摸事件做处理了,但是当菜单内的滚动需要保持时,菜单内的内容滑倒底部或顶部时还是会引起底层的滚动,在电脑端可以直接通过 overflow:hidden 来禁止滚动条从而达到不可滚动的效果,但是在移动端,是基于触摸事件的,这个办法不兼容,后来在网上找资料得知这个现象被称为滚动穿透,有很多大神对这个问题进行了分析提出来各种不同的解决方案。
我也是跟着教程不断的摸索、测试,一遍又一遍的修改,终于在前几天的一个晚上,找到了一个可行的办法解决这个问题,下面是解决方案:
当菜单展开时,给 body 添加 overflow:hidden 的同时再添加 position:fixed,使其绝对定位固定在顶部,此时底层就不会滑动了,但是导致的问题就是页面会跳到顶部,解决跳转到的顶部的方案是获取当前页面滚动条的位置,然后赋值给 body 的 top(需要加上负号),这时当导航菜单展开时页面不会跳到顶部,但是当菜单隐藏时又跳到顶部了,这就还要做一个处理。当菜单隐藏时通过 JS 获取 body 的 top 值,然后转为正数,赋值给变量使页面滚动到之前的位置。
经过一番折腾终于算是把这个问题解决了,重点来了,虽然以上思路能解决这个问题,但是会导致一个小小的问题,作为有点强迫症的人是不能忍的,就是当菜单展开时虽然不会再跳到顶部,但是偶尔会出现大约 2 像素的偏移,微微的跳动一下,这看起来还是有点扎眼的,就在我纠结于这个问题的时候,我发现了另一个解决这个问题的方案……
只需要在 body 内单独加一个 div 把所有元素包起来,然后给这个 div 设置如下样式:
style="position:absolute;top:0;right:0;bottom:0;left:0;overflow:auto"
就可以让底层在菜单展开并且有内容滚动时不跟着滚动了,而且也不会出现 2 像素的偏移,这算是一个完美的解决方案解决移动端的滚动穿透问题,相比那些用一大段 JS 来各种运算、赋值、判断解决的方法,这个办法真的是超级好用,于是我果断的删除了前面的代码,用上了这个办法,有网友反应这种方式在苹果设备上会导致菜单的内容滚动呆滞,由于我还没有苹果设备,这个没有测试,欢迎大家反馈。
另外在折腾这个解决方案的同时我发现了一个神奇的样式:
-ms-overflow-style:none
这个样式竟然能够隐藏 IE 浏览器的滚动条!这个效果是我以前想实现一直没实现的,想到以前试图隐藏 IE 滚动条查到的方案都不靠谱时,我觉得这个样式真是神奇般的存在,于是果断把自己博客的滚动条隐藏了……
在折腾这些问题的时候,我越来越发现 CSS 与 JS 的强大,基本上出现的问题都有办法得到解决,也越来越感叹自己懂的技术还是太少了,学习的道路还很远。