长列表滚动时可视区域高度计算不准怎么办?

码农誉琳 阅读 38

我在用虚拟滚动优化长列表时,发现可视区域高度总是比实际窗口小20px,导致最后几项提前渲染了。之前用window.innerHeight计算容器高度,但加了padding后问题更严重了。

尝试改用容器的getBoundingClientRect(),代码如下:


const container = this.$refs.listContainer;
const viewportHeight = container.getBoundingClientRect().height;
const start = Math.floor((scrollTop) / itemHeight);
const end = Math.ceil((scrollTop + viewportHeight) / itemHeight);

滚动到中间位置时发现end值比预期小,导致底部3项没被渲染。检查发现计算scrollTop时用了container.scrollTop,但容器外层有另一个父元素设置了overflow,实际滚动条在父元素上。该怎么正确获取相对可视区域的滚动位置呢?

我来解答 赞 5 收藏
二维码
手机扫码查看
2 条解答
Top丶俊俊
我一般直接用 document.scrollingElement 来拿正确的滚动位置,别管那些乱七八糟的父元素。代码改一下:


const container = this.$refs.listContainer;
const parentScroll = document.scrollingElement || document.documentElement;
const scrollTop = parentScroll.scrollTop;
const viewportHeight = container.getBoundingClientRect().height;
const start = Math.floor(scrollTop / itemHeight);
const end = Math.ceil((scrollTop + parentScroll.clientHeight) / itemHeight);


这样就不用纠结容器的嵌套问题了,省事。
点赞
2026-02-16 18:04
Good“艳雯
你这种情况我之前也遇到过。核心问题是获取滚动位置和容器尺寸的参照系不一致导致的,需要用相对定位的方式来计算。

正确的做法是用getBoundingClientRect()获取容器的位置信息,结合window.scrollY来计算实际可视区域的滚动位置。修改代码如下:


const container = this.$refs.listContainer;
const rect = container.getBoundingClientRect();
const viewportTop = rect.top + window.scrollY;
const viewportHeight = rect.height;
const scrollTop = viewportTop - (container.offsetParent ? container.offsetParent.scrollTop : 0);
const start = Math.floor(scrollTop / itemHeight);
const end = Math.ceil((scrollTop + viewportHeight) / itemHeight);
点赞 5
2026-02-06 08:04