在一些场景中,比如弹出一个带滚动条的浮窗,为了避免在操作时触发原生滚动条,这时我们需要禁用掉浏览器的滚动条。
常用的三种方法如下。
方法一
让body不能滚动。
export const forbidBodyScoll = () => {
const body = window.document.getElementsByTagName('body')[0];
body.style.overflow = 'hidden';
};
export const allowBodyScoll = () => {
const body = window.document.getElementsByTagName('body')[0];
body.style.overflow = 'initial';
};
优点:实现简单。
缺点:改变了body的overflow属性,可能会导致布局异常。
方法二
重置滚动条。
let isBodyCanScroll = true;
let lastBodyScrollTop = 0;
window.addEventListener('scroll', () => {
if (!isBodyCanScroll) {
window.scrollTo(0, lastBodyScrollTop)
}
})
export const forbidBodyScroll = () => {
isBodyCanScroll = false
lastBodyScrollTop = window.scrollY
}
export const allowBodyScroll = () => {
isBodyCanScroll = true
}
优点:不影响任何布局。
缺点:一直在执行滚动事件,可能存在性能问题。
方法三
修改body的定位。
let lastBodyScrollTop = 0;
let isBodyCanScrollUsePosition = true;
export const forbidBodyScrollUsePosition = () => {
const bodyDom = document.getElementsByTagName('body')[0];
isBodyCanScrollUsePosition = false
lastBodyScrollTop = window.scrollY;
bodyDom.style.position = 'fixed';
bodyDom.style.overflow = 'hidden';
bodyDom.style.top = '0px';
bodyDom.style.left = '0px';
bodyDom.style.right = '0px';
bodyDom.style.bottom = '0px';
bodyDom.style.marginTop = `${-lastBodyScrollTop}px`;
}
export const allowBodyScrollUsePosition = () => {
const bodyDom = document.getElementsByTagName('body')[0];
bodyDom.style.position = 'relative';
bodyDom.style.overflow = 'auto';
bodyDom.style.top = 'unset';
bodyDom.style.left = 'unset';
bodyDom.style.right = 'unset';
bodyDom.style.bottom = 'unset';
bodyDom.style.marginTop = 'unset';
if (!isBodyCanScrollUsePosition) {
window.scrollTo(0, lastBodyScrollTop)
}
}
优点:实现简单,而且保证了body的滚动位置,第一种方法在某些情况下,可能丢失body的滚动位置。
缺点:修改了body的overflow,可能导致有些布局收到影响。
可以结合具体使用场景,选择使用上面的方法。如果你有其他方法,可以在文章底部留言。