填坑小能手——滚动嵌套

前言

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

问题

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

原文链接:https://juejin.cn/post/7313845376228950053 作者:躺平使者

(0)
上一篇 2023年12月19日 上午10:41
下一篇 2023年12月19日 上午10:52

相关推荐

发表回复

登录后才能评论