原生不支持虚拟滚动,因其渲染由系统控件接管,DOM不可干预;bootstrap-select等方案通过自定义实现虚拟滚动,手写需撑高容器、监听滚动、计算索引、局部更新。

原生 不支持虚拟滚动,硬塞 10 万条 会卡死浏览器——这不是配置问题,是 DOM 渲染机制决定的。必须换方案。
为什么原生 select 无法开启虚拟滚动
浏览器对 的渲染完全由系统控件或 UA 样式接管,DOM 层面不可干预。你无法监听其滚动、劫持渲染、动态替换 节点。所有“给 select 加 overflow”“用 CSS 模拟滚动”的尝试,最终都只是在伪造滚动行为,实际仍加载全部选项。
- 设置
size="20"只是让下拉变成固定行数的列表框,不减少 DOM 节点 -
overflow: auto对原生无效(除非用size触发列表框模式,但依然全量渲染) - 任何试图用 JavaScript 动态增删
来模拟滚动的方案,都会因频繁 DOM 操作导致掉帧甚至卡死
bootstrap-select 的 virtualScroll 是怎么工作的
它根本没用原生 核心就四步:撑高容器、监听滚动、算索引、局部更新。不需要框架,纯 JS + HTML 就能跑: 注意:单项高度必须是固定值(不能用 em/%),否则计算会漂移;滚动事件要防抖,避免高频重绘。 移动端 Safari 和旧版 Chrome 对 真正的大数据选择场景,从来不是“怎么让 select 滚起来”,而是“什么时候该放弃 select”。虚拟滚动只是过渡方案,最终往往要换成 searchable combobox 或异步搜索 + 分页加载。,而是用 + 完全重写了下拉菜单 UI,并在内部实现了一套滚动位置映射逻辑:只生成当前可视区域的 ,滚动时通过 scrollTop 计算起始索引,再用 slice() 截取数据子集重新渲染。
data-virtual-scroll="true" 或 data-virtual-scroll="600"(≥600 项自动触发)data-size(如 data-size="8")设定菜单高度,否则无法计算可视行数data-live-search="true" 强烈建议开启,否则用户根本没法在 10 万条里定位不用第三方库时怎么手写最小可行虚拟滚动
<div class="virtual-select" style="height: 200px; overflow-y: auto;">
<div class="full-height-box" style="height: 1000000px;"></div>
<ul class="visible-list"></ul>
</div>
full-height-box 高度 = 单项高度 × 总数据条数(比如 32px × 100000 = 3.2e6px),用来撑开滚动空间virtual-select 的 scroll 事件,读取 scrollTop
Math.floor(scrollTop / 32),结束索引 = 起始 + Math.ceil(200 / 32) ≈ 7data.slice(start, end) 获取子数组,清空 .visible-list 后批量插入
容易被忽略的兼容性坑
scrollTop 的精度处理不一致,尤其在快速滑动时可能跳帧或索引错位。
scrollHeight 做计算,它在某些安卓 WebView 里返回 0scroll 回调里直接操作 DOM,改用 requestIdleCallback 或节流到 16ms 一帧),虚拟滚动需额外维护分组头位置,原生 bootstrap-select 的 virtualScroll 不支持分组渲染
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











