仅提供语义化网格结构,原生不支持编辑、公式等功能;需用js补足键盘导航、粘贴解析、焦点管理等交互,并注意无障碍属性(如role="grid")和性能优化。

用 <table> 实现基础网格,但别指望它像 Excel
<p>HTML 本身没有“电子表格控件”,<code><table> 只是语义化表格结构,不带编辑、公式、冻结行列等功能。如果你需要用户双击编辑、按回车跳格、Ctrl+C/V 表格区域——<code><table> 原生做不到,得靠 JS 补足。
<p>常见错误:直接给 <code><td> 加 <code>contenteditable="true" 就以为是电子表格了。结果发现 Tab 键不跳格、方向键不能选区、粘贴多行内容会错位、没单元格边框样式还容易点不准。
- 真要轻量编辑,至少加
tabindex + 监听 keydown 处理 Tab/方向键
- 默认
<td> 不响应 <code>:focus,得设 outline: none 并手动加聚焦样式(比如背景色)
- 边框建议用
border-collapse: collapse 配合 border: 1px solid #ccc,否则双线难看又难调试
contenteditable 单元格的三个硬伤和绕过方法
很多人卡在粘贴行为上:Ctrl+V 粘贴 Excel 复制的内容,浏览器默认把它当富文本塞进单个 <td>,而不是拆成多行多列。
<ul><li>解决粘贴:监听 <code>paste 事件,用 event.clipboardData.getData('text/plain') 拿纯文本,再按 \t 和 \n 切分,动态插入新 <tr>/<code><td>
<li>方向键不移动焦点?给每个 <code><td> 绑 <code>keydown,捕获 ArrowUp/Down/Left/Right,用 element.focus() 切到相邻单元格(注意边界判断)
- Enter 键默认换行,不是跳到下一行?加
event.preventDefault(),然后手动 focus 下行同列单元格
性能瓶颈在哪:100×100 表格卡顿的根源
不是 DOM 多,是重排(reflow)太勤。每次修改一个 <td> 的 <code>innerText 或 class,浏览器都可能触发整行甚至整表重绘。
- 避免高频操作中直接改
innerHTML;批量更新用 DocumentFragment 或先 detach 再 append
- 别给每个
<td> 加独立事件监听器——用事件委托,<code><table> 上统一只监听 <code>click/keydown
- 滚动时卡?给
<tbody> 加 <code>overflow-y: auto 和固定高度,但必须设 display: block,此时 <tr> 会失效,得用 <code>div 模拟行和单元格(即“虚拟滚动”雏形)
该不该自己写?对比 handsontable 和 gridjs 的现实代价
写一个能撑住 500 行、支持筛选、排序、导出 Excel、兼容 IE11 的表格,投入远超预期。社区方案不是银弹,但省掉 80% 边界 case。
-
handsontable 功能全但体积大(gzip 后约 120KB),免费版禁用导出和多层撤销
-
gridjs 轻量(gzip 后 ~25KB),API 简洁,但原生不支持单元格合并或公式
- 如果只要展示+简单编辑,用
<table> + 手动补交互更可控;如果要协作、历史版本、条件格式,别硬刚,直接集成
<p>最常被忽略的一点:键盘导航的无障碍支持(<code>role="grid"、aria-rowindex、roving tabindex)几乎没人做,但却是企业级应用上线的硬门槛。
tabindex + 监听 keydown 处理 Tab/方向键<td> 不响应 <code>:focus,得设 outline: none 并手动加聚焦样式(比如背景色)
border-collapse: collapse 配合 border: 1px solid #ccc,否则双线难看又难调试
contenteditable 单元格的三个硬伤和绕过方法
很多人卡在粘贴行为上:Ctrl+V 粘贴 Excel 复制的内容,浏览器默认把它当富文本塞进单个 <td>,而不是拆成多行多列。
<ul><li>解决粘贴:监听 <code>paste 事件,用 event.clipboardData.getData('text/plain') 拿纯文本,再按 \t 和 \n 切分,动态插入新 <tr>/<code><td>
<li>方向键不移动焦点?给每个 <code><td> 绑 <code>keydown,捕获 ArrowUp/Down/Left/Right,用 element.focus() 切到相邻单元格(注意边界判断)
event.preventDefault(),然后手动 focus 下行同列单元格性能瓶颈在哪:100×100 表格卡顿的根源
不是 DOM 多,是重排(reflow)太勤。每次修改一个 <td> 的 <code>innerText 或 class,浏览器都可能触发整行甚至整表重绘。
- 避免高频操作中直接改
innerHTML;批量更新用DocumentFragment或先 detach 再 append - 别给每个
<td> 加独立事件监听器——用事件委托,<code><table> 上统一只监听 <code>click/keydown - 滚动时卡?给
<tbody> 加 <code>overflow-y: auto和固定高度,但必须设display: block,此时<tr> 会失效,得用 <code>div模拟行和单元格(即“虚拟滚动”雏形)该不该自己写?对比
handsontable和gridjs的现实代价写一个能撑住 500 行、支持筛选、排序、导出 Excel、兼容 IE11 的表格,投入远超预期。社区方案不是银弹,但省掉 80% 边界 case。
-
handsontable功能全但体积大(gzip 后约 120KB),免费版禁用导出和多层撤销 -
gridjs轻量(gzip 后 ~25KB),API 简洁,但原生不支持单元格合并或公式 - 如果只要展示+简单编辑,用
<table> + 手动补交互更可控;如果要协作、历史版本、条件格式,别硬刚,直接集成 <p>最常被忽略的一点:键盘导航的无障碍支持(<code>role="grid"、aria-rowindex、roving tabindex)几乎没人做,但却是企业级应用上线的硬门槛。
-
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











