Moonofweisheng / wot-design-uni

一个基于Vue3+TS开发的uni-app组件库,提供70+高质量组件,支持暗黑模式、国际化和自定义主题。
https://wot-design-uni.pages.dev
MIT License
639 stars 94 forks source link

微信小程序将顶部的元素设置sticky时,粘性会失效 #325

Closed Yi-Wo-Zuo closed 1 month ago

Yi-Wo-Zuo commented 1 month ago

Wot Design Uni 版本号

^1.2.20

平台

微信小程序

复现Demo地址

重现步骤

WeChat045ffd974fb8d80ce514eca379e1418d

向下滚动,这个顶部元素没有粘性功能

期望的结果是什么?

可以粘性在顶部

实际的结果是什么?

没有粘性在顶部

环境信息

其他补充信息

问题排查

这里我看了具体的源码实现我进行了断点调试,如下代码:

WeChat64a43db6eabbde9d8c0ad50ca3468e3c

这个回调函数里的boundingClientRect参数里面的top值并不是0px而是17px我就觉得很不理解

我就去看了wd-resize组件的resize方法

WeChat0d55ec1b404c00cf69336f3166dd7c3f

我在onScrollHandler里打了一个debugger,惊奇的发现当debugger触发时,使用wd-sticky组件的元素是向上有一定的距离

WeChat92a618447edbfc6ebf842d81a82c93df

看到了wd-sticky里面的动态宽高还没有内容就调用了这个方法

解决

我使用nextTick函数包裹了一些就解决,目的是为了宽高样式加上后,在获取DOM的样式

WeChatfdaca8f2f065b1cfdfaf7c4605dd8ee2

我这个方法不一定对,因为我也不清楚这个组件的具体逻辑,发出来我觉得作者有更好的解决方法

Moonofweisheng commented 1 month ago

大概问题是这样的:sticky使用IntersectionObserver实现的监听组件是否与视口范围有交叉,有交叉就回设置吸顶,视口范围为视口高度减去吸顶组件高度,而组件初始就放在顶部,则导致其始终都在视口范围外不会交叉,所以首次渲染时组件会模拟一次滚动,也就是你添加nextTick的地方,这里原来的实现是在设置style后立即执行获取节点信息,而这个时机在微信小程序上获取的节点信息是更新前的,这就导致未获取到真实的节点信息,进而使得模拟滚动的结果无效,而滚动页面又无法使sticky与视口存在交叉,所以吸顶就失效了。