如何在弹层弹出时阻止底部滑动 最佳方案
网上对这个问题的解答众说纷纭,总结来看原理就下面这几种:
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 那么此时的代码则是
<body style="position:fixed">
<section style="position:fixed;top:-500px">
<!-- 不想滚动的区域 -->
</section>
<section>
<!-- 弹层区域 -->
</section>
</body>
具体的逻辑代码,如何操作dom结构就不写了, 大家应该也会,只要理解了这个原理,不论是使用jq还是原生,使用vue或者react等的框架,都可以这样解决弹层滑动问题。