如何在弹层弹出时阻止底部滑动 最佳方案
网上对这个问题的解答众说纷纭,总结来看原理就下面这几种:
1.阻止 body 滚动的默认行为:
在弹层弹出后给 body 添加 onscroll 事件(移动端阻止 ontouchmove),并通过 preventDefault 让 body 不能滚动,这样的优点是代码量少,能达到一定的效果。但同时缺点也是显而易见的,这样的做法在弹层内容不需要滚动的情况下可以使用,但是在弹层内容也需要滚动的情况下就不行了。
2.body 设置 overflow:hidden:
这种方法通过在弹层弹出后给 body 设置样式 height:100%;overflow:hidden,让 body 无法滚动,亲测 pc 端可以,移动端不起作用(猜测是移动端浏览器的问题),具体原因还请大神来解答。如果不需要考虑移动端,可以使用这种方法,代码也很简洁。
3.body 设置 position:fixed :
在弹层弹出后给 body 设置 position:fixed, pc 端移动端都可以,但是会强制滚动到页面顶部(因为此时 body 已经不能滚动了。scrollTop 被重置为 0),这种方法是最接近完美的解决方法,所以完美的解决办法就是这种方法的增强版。
完美的解决方案:
在将要弹出弹层时候记录当前滚动的位置,将 body 设置为固定定位之后,再将实际显示的区域(不想滚动的区域)最外层进行定位,并将 top 值设置为负的滚动位置值,这样就不会在弹出弹层之后回到页面顶部,然后在弹层关闭后解除 body 的固定定位以及之前不想滚动区域的定位,并滚动到之前记录的位置(设置 scrollTop 的值)。这样就完美解决了弹出弹层后底部会滑动的问题,并且弹层内容可滑动。
示例: 假如已经滚动了 500px 那么此时的代码则是
1 | <body style="position:fixed"> |
具体的逻辑代码,如何操作 dom 结构就不写了, 大家应该也会,只要理解了这个原理,不论是使用 jq 还是原生,使用 vue 或者 react 等的框架,都可以这样解决弹层滑动问题。