小数据量(几千条内)用前端分页,上万条须后端分页;前端通过 slice 控制 tr 显隐,用 querySelectorAll 缓存行元素,按 pageSize 和 currentPage 计算范围并设置 display。
小数据量(几千条以内)直接用 JavaScript 前端分页就行;上万条起步,必须切到后端分页,否则页面卡死、内存爆掉是常态。
slice() 控制表格行显隐核心不是重绘整个表格,而是动态控制 <tr> 的 display 状态。直接操作 DOM 比反复 innerHTML = ... 更轻量、更可控。
document.querySelectorAll('table tbody tr') 拿到所有数据行,存成数组,避免每次翻页都重新查 DOMpageSize = 10,当前页码 currentPage = 1
const start = (currentPage - 1) * pageSize,const end = start + pageSize
rows[i].style.display = i >= start && i
visibility: hidden —— 它仍占布局空间,会导致表格高度异常page 和 pageSize
前端发请求时,只传这两个参数就够了,别拼错名,也别漏掉校验。后端返回的数据结构里,必须包含 list(当前页数据)和 total(总条数),缺一不可。
list,前端算不出总页数 → 分页控件无法生成页码按钮/api/users?page=2&pageSize=20,不是 /api/users/2 这种路径式写法(不易维护、不通用)tbody 再用 insertRow() 或 innerHTML 渲染,别忘了更新页码状态(比如禁用“下一页”按钮)offset —— 容易被用户篡改导致越界查询按钮没禁用、页码跳转后状态没同步、点击空白处触发多次,这些问题几乎都出在事件绑定和状态管理上。
立即学习“前端免费学习笔记(深入)”;
currentPage === 1 时,务必设 disabled 属性并加 CSS 灰色态,不能只靠 JS 判断跳过逻辑for 循环动态生成时,别用闭包传参(let i 要写对),更推荐用 data-page 属性 + event.target.dataset.page
document.querySelector('tbody').scrollIntoView({ block: 'nearest' }),否则用户可能看不到新内容disabled,请求完成再恢复,否则快速连点会发多个重复请求最常被忽略的是错误边界:网络失败时没 fallback 提示,total 返回 null 或 0 时没兜底逻辑,还有移动端点击区域太小导致误操作——这些细节不处理,分页功能就算写完了,也撑不过真实用户三分钟。