js实现虚拟表格
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 | <! DOCTYPE html> < html lang="en"> < head > < meta charset="UTF-8"> < meta http-equiv="X-UA-Compatible" content="IE=edge"> < meta name="viewport" content="width=device-width, initial-scale=1.0"> < title >虚拟表格</ title > < style > * { padding: 0; margin: 0; } #list { width: 300px; height: 500px; overflow-y: auto; position: relative; } #parent { position: relative; width: 100%; } #content { -webkit-willChange: 'transform'; willChange: 'transform'; position: absolute; width: 100%; left: 0; top: 0; } #bg { position: absolute; z-index: 10; width: 100%; height: 100%; top: 0; left: 0; background: #fff; opacity: 0; display: none; } .item { min-height: 50px; margin-bottom: 5px; border: 1px solid #ccc; display: flex; justify-content: center; align-items: center; } </ style > </ head > < body > < div id="list"> < div id="parent"> <!-- 用来装载内容 --> < div id="content"></ div > <!-- 用来遮挡渲染内容,避免鼠标在不断渲染的content上面的时候导致卡顿无法触发滚动 --> < div id="bg"></ div > </ div > </ div > < script > let itemNum = 100; // 内容总数 let itemHeight = 52; // 每个内容单元高度 let list = document.getElementById('list') let parent = document.getElementById('parent') parent.style.height = `${itemNum*itemHeight}px` // 内容总高度撑开滚动条 let content = document.getElementById('content') let bg = document.getElementById('bg') let cNum = Math.ceil(list.offsetHeight / itemHeight) // 可视区域个数 let startIndex = 0 // 可视区域开始index let endIndex = startIndex + cNum // 可视区域结束index let data = [...new Array(itemNum).keys()] // 生成所有数据 // 渲染初始数据 data.slice(startIndex, endIndex).forEach(item => { let div = document.createElement('div') div.innerHTML = item div.setAttribute('class', 'item') content.appendChild(div) }) let timer = null; // 滚动定时器,用于检测是否滚动结束 let scrollTop = 0; // 当前滚动条高度 let scrollEndTop = 0; // 停止时滚动条高度 function scrollCallBack() { clearTimeout(timer); timer = setTimeout(isScrollEnd, 500); scrollTop = list.scrollTop bg.style.display = 'block' let sTop = Math.max(list.scrollTop, 0) // 滚动距离,最小取0 startIndex = Math.floor(sTop / itemHeight) // 可视区域开始index endIndex = startIndex + cNum // 可视区域结束index content.style.transform = `translateY(${startIndex*itemHeight}px)` // 内容区域偏移 // 新的数据渲染 let newData = data.slice(startIndex, endIndex) let html = '' newData.forEach(item => { html += `< div class="item">${item}</ div >` }) content.innerHTML = html } // 判断是否滚动结束,将bg遮罩层隐藏 function isScrollEnd() { scrollEndTop = list.scrollTop; if (scrollTop === scrollEndTop) { console.log('滚动条停止滚动'); bg.style.display = 'none' } } scrollCallBack() list.addEventListener('scroll', scrollCallBack) </ script > </ body > </ html > |
放弃安逸,持续努力——成长
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧