填坑小能手——滚动嵌套

前言

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

问题

为了研究现场问题,我们先写一个滚动嵌套的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的认知,大家如果碰到类似问题,可以从以上两方法考虑,一个样式;一个事件。

相关推荐
清风絮柳8 分钟前
59.基于ssm和vue学生考试成绩管理系统
前端·javascript·vue.js·毕业设计·ssm架构·学生考试成绩管理系统·学生考试成绩管理
风雨兼程^_^38 分钟前
Nuxt3项目的SEO优化(robots.txt,页面tdk,伪静态.html,sitemap.xml动态生成等)
前端·seo·nuxt3·服务端渲染ssr
佬乔40 分钟前
xml中配置AOP织入
java·服务器·前端
Eugene__Chen42 分钟前
JavaWeb开发基础知识-XML和JSON
java·开发语言·前端
谢尔登1 小时前
为 IDEA 设置管理员权限
前端·express
Kx…………1 小时前
Uni-app入门到精通:uni-app的基础组件
前端·css·学习·uni-app·html
巴巴博一1 小时前
keep-alive缓存
前端·javascript·vue.js·缓存·typescript
Tipriest_1 小时前
【前端扫盲】postman介绍及使用
前端·测试工具·postman
wuaro2 小时前
JS的深浅拷贝
前端·javascript·html
苹果酱05672 小时前
SpringCloud第二篇:注册中心Eureka
java·vue.js·spring boot·mysql·课程设计