Search Docs
通过setInterval定时器分批插入元素,每次处理一定数量的节点
setInterval
export default (element, data) => { const fragment = document.createDocumentFragment() let timer = setInterval(() => { for (let i = 0; i < 20; i++) { const item=data.shift() if(!item){ clearInterval(timer) break } const div=document.createElement('div') fragment.appendChild(div) // 设置div属性和样式 } element.appendChild(fragment) }) }
使用requestAnimationFrame来替代setInterval,它会在浏览器下一次重绘之前执行回调函数
requestAnimationFrame
export default (element, data) => { requestAnimationFrame(() => stop(element, data)) const stop = (element, data) => { const fragment = document.createDocumentFragment() for (let i = 0; i < 20; i++) { const item = data.shift() if (!item) { break } } const div = document.createElement('div') fragment.appendChild(div) } element.appendChild(fragment) data.length && requestAnimationFrame(() => stop(element, data)) }
仅渲染可视区域的数据,随着用户的滚动,动态添加或删除DOM节点
position:relative
position:absolute
transform
export default (element,data)=>{ const boundary=[0,0] let startIndex=0 let endIndex=0 const step=10 const threshold=200 // 初始化和事件绑定了 const createElement=(item,mode)=>{ const div=document.createElement('div') // 设置属性和样式 return div } const initScroll=(element)=>{ element.addEventListener('scroll',scroll(element,(e)=>{ // 根据滚动事件添加或删除DOM节点 }) } } // 其他辅助函数
虚拟滚动的关键点: