臭名昭著的前端滚动穿透问题,今天也遇到了,网上找来的大概有三种解决方案!
1. css之overflow:hidden
1 2 3 4 |
html, body { overflow: auto; height: 100%; } |
当弹出蒙层时,禁用了html和body的滚动条,滚动列表的滚动位置会丢失, 需要使用js来还原,
document.scrollingElement.scrollTop 获取滚动条的距离, 然后还原!
但是我需要一打开弹窗就固定背景的位置, 所以直接pass!!!
2. touchmove + preventDefault
在弹出的提示框中阻止浏览器的默认行为以及冒泡行为,在可以滑动的dom元素中取消浏览器的默认行为以及冒泡行为
1 2 3 4 5 6 7 8 9 10 |
let stop = document.querySelector("#tm"); stop.addEventListener("touchmove", (event) => { event.preventDefault(); //阻止默认行为 event.stopPropagation(); //阻止冒泡 }, false) let cancelStop = document.querySelector(".allReason"); cancelStop.addEventListener("touchmove", (event) => { event.returnValue = true; //取消阻止默认行为 event.cancelBubble = true; //取消阻止冒泡 }, false) |
使用这种方法会有一个缺点,那就是滑动其它地方,底部页面不会滚动,但是在可以滑动的页面中,将其滑动到底部或者顶部后继续滑动,底部页面任然可以滚动!
而且经过测试, ios11以上版本均无效!!! 还是可以滑动!!!
3. css 之 position: fixed + js 滚动条的位置
在弹出遮罩层的时候给body添加样式以及获取滚动条的位置,
在关闭遮罩层的时候移除body的样式以及设置滚动条的位置
1 2 3 4 |
.scroll { position: fixed; width: 100%; } |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
var scroll = (function (className) { var scrollTop; return { afterOpen: function () { scrollTop = document.scrollingElement.scrollTop || document.body.scrollTop; document.body.classList.add(className); document.body.style.top = -scrollTop + 'px'; }, beforeClose: function () { document.body.classList.remove(className); document.scrollingElement.scrollTop = scrollTop; document.body.scrollTop = scrollTop; } }; })('scroll'); |
最终结果如下:
最终完美解决!
累累累!!!