禁止特定区域的鼠标滚动导致的页面整体滚动

今天接到一个bug修复需求:当用户在左侧菜单栏底部继续滚动鼠标时,右侧的主体内容产生了滚动现象,这个应该被禁止,即:菜单栏的滚动不应该影响右侧主体内容。

一起养成写作习惯!这是我参与「掘金日新计划 · 4月更文挑战」的第4天,点击查看活动详情

经过一些调研和资料的搜索后,我总结出两个方案:

  • 鼠标进入左侧底部区域时,隐藏主体内容容器的滚动条,把滚动条隐藏了,自然也就无法滚动了。
  • 给左侧底部区域添加滚动监听事件,阻止默认行为(即触发、传播页面滚动的行为)

隐藏滚动条

要隐藏某个元素的滚动条我们需要下面的样式:

.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的方式直接在节点上监听,而是通过类似useRefhook的方式获取DOM节点的应用后通过上述原生的方式来监听,hook里记得返回事件监听的移除代码。

总结

第一种的缺点比较明显:

  • 额外的css代码(包括兼容性代码)
  • 滚动条可视性的切换会导致页面内容盒子尺寸的变化,内容盒子的尺寸变化会带来页面的重排。
  • 存在一定的耦合,一旦主体页面容器发生更改没有及时同步会导致代码失效

再来看第二种,没有上述的缺点,也更加简单,我果断选择了第二种。

猜你喜欢

转载自juejin.im/post/7085915795892469774