-
Notifications
You must be signed in to change notification settings - Fork 350
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[tree] 使用虚拟滚动的树形组件,滚动条滑块的高度不正常 #2288
Comments
👋 @sagittarius-rev,感谢给 TDesign 提出了 issue。 |
|
目前虚拟滚动复用了 table 的虚拟滚动代码,先解决了有没有这个能力的问题。 |
Table 的虚拟滚动,支持预估滑块的默认高度, 是按比例来的,可以参考下 @TabSpace 大概原理是: |
tdesign-vue 版本
tdesign-vue 1.2.3
重现链接
https://codesandbox.io/s/tdesign-vue-demo-forked-zp2xje?file=/src/demo.vue
重现步骤
使用树形组件,启用虚拟滚动功能,
type
设置为"virtual"
。在组件内使用数量较多的节点。滚动界面。
期望结果
右侧滚动条的滑块应当正常显示。按照当前可见区域的高度,以及整棵树渲染出来的高度,滑块高度应当遵循两者的比例。
也就是,树高度越大,滚动条滑块的高度应当越小,两者成反比关系(假设可见区域的高度不变)。
在纵向滚动过程中,滑块的高度应当不发生变化,只是位置在移动。
实际结果
初始情况下,滑块高度较大。而随着向下滚动,滑块会逐渐缩小。
如果数据量较多,拖动滚动条时,无法一次拖动就滚动到底部。需要分很多次进行滚动操作,才能到底。
框架版本
Vue(2.6.14)
浏览器版本
Chrome(109.0.5414.120)
系统版本
Windows 10
Node版本
16.16.0
补充说明
问题原因分析
虚拟滚动的树形组件,在组件上设置了
overflow: scroll
样式。右侧的滚动条是由浏览器自行渲染出来的。而浏览器计算滚动条滑块高度时,会根据当前组件的实际占据范围为依据。使用虚拟滚动功能的时候,树形组件内只渲染了部分节点,并设置
transform: translate()
的样式进行位移。这样,浏览器计算树形组件占据的范围时,会以位移之后的节点组件底部为依据。在初始情况下,渲染出来的节点会比可见范围能容纳的节点多一些,根据
bufferSize
属性的设置决定。此时,浏览器认为树形组件的实际高度范围只比可见区域高度多一些,因此计算出来的滚动条滑块高度就较大。而随着不断向下滚动,渲染出来的可见节点在发生变化,位移值也在增加。因此,浏览器认为树形组件占据的高度范围在增加,滚动条滑块的高度就随之减少了(如前面所述的反比关系)。
解决方案
在树形组件内部附加一个用于占位的元素,可以设为不可见(不使用
display: none
,而是使用opacity: 0
或visibility: hidden
)。元素使用绝对定位,其纵向位置是动态计算的,相当于整棵树渲染出来时最后一个节点的底部位置。有了这个占位元素之后,浏览器就能正确判断树形组件应当占据的有效高度范围,从而正常渲染滚动条的滑块高度。而这个高度在滚动过程中不会发生变化。
重现链接中就实现了对应的功能。点击页面上的“插入定位锚点”按钮,就会插入前述的占位元素,保证滚动条外观正常。而在节点展开/折叠的时候,会重新计算该元素的位置(理论上在数据重置、增加项目、减少项目时,也应当进行重算,但示例代码未进行这些处理)。
理论上只要每行的高度是固定的,那么只要知道有多少元素应当被显示,就能计算出占位元素的纵向位置。
但目前 TDesign 的树形组件没有暴露出相关的处理方法或属性。因此重现链接中的代码是通过一些内部属性来对此进行计算的:
代码比较丑陋。
希望官方能内置相关的特性支持。
The text was updated successfully, but these errors were encountered: