填坑小能手——滚动嵌套

前言

前两天开心地摸着鱼,现场项目就提出了与滚动嵌入相关的问题:子元素滚动条滚动时外层滚动条滚动了,让修改为外层不滚动。卑微打工人只能乖乖去解决,下面来看下解决过程。

问题

为了研究现场问题,我们先写一个滚动嵌套的demo,看下滚动嵌套具体的行为。

根据图上的行为我们可以得出,子元素滚动条不到边缘时不会影响父元素滚动条,当滚动条到边缘时才会影响父元素。有没有什么办法取消影响呢?网上搜索下,发现了overscroll-behavior 属性。 overscroll-behavio可以控制滚动条滚动到边界的表现。该属性有三个值:

  • auto:默认值,具体表现就是图中所示。
  • contain:临近滚动区域不会被影响。
  • none:临近滚动区域不受影响并且阻止滚动到边界的行为。
    所以只要将overscroll-behavior的值设置为后两个就能解决我们的问题。添加overscroll-behavior属性后在页面尝试滚动,当子元素滚动跳触底后再次滚动父元素滚动条不动。接下来去项目中找到子元素添加overscroll-behavior属性就可以了。

解决

当我信心满满去找相关代码时,发现子元素的滚动条是用BS写的,滚动条表现跟上述分析的也不一样,只要子元素滚动外部滚动条就会滚动。叹口气决定死马当活马医,给子元素添加overscroll-behavior属性,结果并不生效,只好从BS入手。 BS是专门做滚动的库,支持各种各样与滚动相关的功能,公司项目是pc端,只是简单用到了鼠标滚轮与滚动条功能:

又观察了几次项目bug行为,发现BS包裹的元素滚动跟外层是同时进行的,有点像冒泡事件,子元素的滚动行为冒泡导致父元素也进行了滚动,感觉可以从元素事件入手。照着这个思路,检查了配置项又查阅BS官方文档发现了preventDefault属性,该属性用来阻止浏览器事件派发后的默认行为,默认为true,而配置项设置了false,浏览器行为都放开了,所以BS的滚动事件触发了浏览器的滚动行为。那么我们把preventDefault去掉就能解决问题,设置好再次尝试发现BS滚动条滚动并没有影响外层滚动条滚动。 虽然解决了滚动问题,但是引入了新问题,本身设置preventDefault为false就是不让阻止默认事件,跟之前的需求冲突了。幸好BS也考虑到了这个问题,定义了两个与之相关的属性:

  • preventDefaultException:后面跟正则表达式,匹配到的元素不会被阻止默认事件。
  • tagException:也是跟正则表达式,匹配到的元素不会影响BS滚动。
    刚开始我用了preventDefaultException发现不生效,后面用了tagException完美解决,官方文档上没有明确tagException此功能,果然还是得看实际操作啊。

总结

以上就是滚动嵌套问题的解决,解决过程中认识到了overscroll-behavior属性,顺带加深了对BS的认知,大家如果碰到类似问题,可以从以上两方法考虑,一个样式;一个事件。

相关推荐
linux_cfan11 分钟前
16 · `custom-media-element`:属性拦截与转发
前端·javascript·音视频
右耳朵猫AI21 分钟前
Web前端周刊2026W38 | React 19.3 发布、StyleX 深潜、jsdom 30.1 提速
前端·javascript·react.js·typescript·node.js
人工智能培训1 小时前
大语言模型:从语言理解到通用智能的跃迁
linux·服务器·前端·人工智能
一拳不是超人1 小时前
做独立开发三个月,我的第一个产品终于有了 1000 个用户
前端·程序员
Amos_Web1 小时前
Rspack 源码解析(十):Hash 与 Asset 生成
前端·rust·源码阅读
福兮说1 小时前
用 IndexedDB 存用户的文件,我踩过的五个坑
前端·javascript
闪耀之光M781 小时前
前端依赖自动导入:unplugin-auto-import
前端
Ricon组态薄荷糖1 小时前
Ricon组态系统:工业组件开发指南与实践
前端·后端·物联网
flash俊杰2 小时前
Electron 桌面应用的进程模型:为什么 fork Next.js standalone
前端
沙蒿同学2 小时前
我把架构约定编译成了会变红的测试:Wails v2 + Go + Vue3 桌面脚手架实战
前端·后端·github