【js】无限虚拟列表的原理及实现
// 创建一个无限滚动的虚拟列表
function createInfiniteScrollList(options) {
// 初始化参数
const itemHeight = options.itemHeight || 20; // 每个条目的高度
const start = options.start || 0; // 起始条目索引
const total = options.total || 1000; // 总条目数
const rowRenderer = options.rowRenderer; // 渲染函数
const container = options.container; // 容器元素
// 计算可视区域的高度
const visibleHeight = container.offsetHeight;
// 计算可以容纳的条目数
const numItems = Math.ceil(visibleHeight / itemHeight);
// 渲染函数,更新DOM
function render() {
for (let i = 0; i < numItems; i++) {
const index = start + i;
if (index < total) {
rowRenderer(index, container);
}
}
}
// 初始渲染
render();
// 监听滚动事件
container.addEventListener('scroll', () => {
const scrollTop = container.scrollTop;
const nextStart = Math.floor(scrollTop / itemHeight);
if (nextStart !== start) {
// 计算新的起始位置
const newStart = Math.max(0, Math.min(nextStart, total - numItems));
const diff = newStart - start;
// 如果需要,移动所有条目来匹配新的起始位置
const items = container.querySelectorAll('.list-item');
for (let i = 0; i < items.length; i++) {
items[i].style.transform = `translateY(${itemHeight * i + diff}px)`;
}
// 更新起始位置
start = newStart;
}
});
}
// 使用示例
const listContainer = document.getElementById('list-container');
createInfiniteScrollList({
container: listContainer,
itemHeight: 50,
total: 10000,
rowRenderer: (index, container) => {
const element = document.createElement('div');
element.className = 'list-item';
element.style.height = '50px';
element.textContent = `Item ${index}`;
container.appendChild(element);
}
});
这段代码实现了一个无限滚动的虚拟列表。它通过监听滚动事件来动态渲染足够多的条目,以便在用户滚动时不会出现性能问题。每次滚动时,只需要移动容器内的条目来保持新的可视区域,而不是重新渲染整个列表。这种方法极大地提高了性能,并提供了流畅的滚动体验。
评论已关闭