禁止特定区域的鼠标滚动导致的页面整体滚动
今天接到一个bug修复需求:当用户在左侧菜单栏底部继续滚动鼠标时,右侧的主体内容产生了滚动现象,这个应该被禁止,即:菜单栏的滚动不应该影响右侧主体内容。
经过一些调研和资料的搜索后,我总结出两个方案:
- 鼠标进入左侧底部区域时,隐藏主体内容容器的滚动条,把滚动条隐藏了,自然也就无法滚动了。
- 给左侧底部区域添加滚动监听事件,阻止默认行为(即触发、传播页面滚动的行为)
隐藏滚动条
要隐藏某个元素的滚动条我们需要下面的样式:
.container.disable-scrollbar {
/* hide scrollbar in firefox */
scrollbar-width: none;
}
.container.disable-scrollbar::-webkit-scrollbar {
display: none;
}
我们需要在鼠标进入左侧底部区域时隐藏滚动条,鼠标移出左侧底部区域时取消隐藏,默认不隐藏:
const bottomEleContainer = ...
const mainEleContainer = ....
bottomEleContainer.addEventListener('mouseenter',()=>{
//激活上述样式
mainEleContainer.className = 'disable-scrollbar'
})
bottomEleContainer.addEventListener('mouseleave',()=>{
//取消激活上述样式
mainEleContainer.className = ''
})
阻止鼠标滚轮的默认行为
这里我们需要给元素添加鼠标滚轮事件的监听:
bottomEleContainer.addEventListener('wheel', (e)=>{
//阻止默认行为(页面的滚动行为)
e.preventDefault()
},{
//这里一定要显式设置为false,因为默认是true
passive: false,
})
如果你使用了React
应该避免直接通过onWheel
的方式直接在节点上监听,而是通过类似useRef
hook的方式获取DOM节点的应用后通过上述原生的方式来监听,hook里记得返回事件监听的移除代码。
总结
第一种的缺点比较明显:
- 额外的css代码(包括兼容性代码)
- 滚动条可视性的切换会导致页面内容盒子尺寸的变化,内容盒子的尺寸变化会带来页面的重排。
- 存在一定的耦合,一旦主体页面容器发生更改没有及时同步会导致代码失效
再来看第二种,没有上述的缺点,也更加简单,我果断选择了第二种。
转载自:https://juejin.cn/post/7085915795892469774