SOURCE

console 命令行工具 X clear

                    
>
console
// 生成数据源,与逻辑无关
let list = [];
for (let i = 0; i < 10000; i++) {
    let id = Math.random();
    (
        function () {
            list.push({ id })
        }
    )(id)
}
// 正式开始
// 获取dom节点
const containerDom = document.querySelector("#container")
const scrollDom = document.querySelector(".virtual-scroll")
const itemDom = document.querySelector("#item-container")
// 设置滚动框架的高度(滚动高度)
containerDom.style.cssText = `height: ${list.length * 30}px;` // 模拟长列表
// 核心
const render = (initIndex = 0, data = []) => {
    const renderData = data.slice(initIndex, initIndex + 10);
    const fragment = document.createDocumentFragment();
    renderData.forEach((item) => {
        const div = document.createElement('div');
        div.innerText = item.id
        div.style.cssText = "height: 30px"
        fragment.appendChild(div)
    })
    itemDom.replaceChildren(fragment)
}
// 初始化
render(0, list)
// 监听滚动条事件重新获取下标并重新渲染
scrollDom.addEventListener('scroll', scrollTarget => {
    render(Math.ceil(scrollTarget.target.scrollTop / 30), list)
})
    // })
<div class="virtual-scroll">
    <div id="container">
      <div id="item-container"></div>
    </div>
</div>
.virtual-scroll {
    width: 200px;
    height: 300px;
    overflow-y: auto;
}

#container {
    background-color: skyblue;
}

#container>div {
    position: sticky;
    /* 这个属性能保证item-container能在渲染区域 哪怕滚动 */
    top: 0;
}