有几个前提条件
容器是黑线框container—绑定scroll事件,故黄色那层wrapper会滚动,里面的蓝色item都相对于黄层绝对定位,且item都是定高—>黄层总高度
黄层一动,蓝色item自然而然就跟着动了。
所以重点在于每次显示的是哪些items,放在一个渲染池中。一滚动后,就得更新渲染池里的数据,同时更新位置信息。
不满足这些条件,尤其是不定高时,虽然有解决办法,但会损耗大量性能,毕竟要重新计算高度导致reflow。
实现—Vue版
// 给黑色层div,即container上,绑定@scroll事件处理函数为setPool
methods: {
setPool(){
const scrollTop = this.$refs.container.scrollTop;//container就是黄层div的ref
const height = this.$refs.container.clientHeight;
let startIndex = Math.floor(scrollTop / this.itemSize);
let endIndex = Math.ceil( (scrollTop + height) / this.itemSize);
startIndex -= prev;// 这是让它前后分别多显示几个item
if(startIndex < 0){
startIndex = 0;
}
endIndex += next;
let startPos = startIndex * this.itemSize
this.pool = this.item.slice(startIndex, endIndex).map((it, idx) => ({
item: it,
position: startPos + i * this.itemSize,//每次滚动后item的起始位置--top值
}));
}
}
有现成的插件
npm install vue-virtual-scroller
RecycleScroller:跟我们实现的是同一类
DynamicScroller: 是item高度不确定的情况下,但是同样,不可避免的会损耗更多的性能