如何实现DataTable子行常显无性能损耗 移除默认绿色展开图标
实现方案
核心改动分两部分,全程无额外性能损耗:
- 移除绿色十字展开控件
- 自动保持所有行的子行持续展开,兼容ajax异步加载、排序、分页、搜索等重绘场景
具体改动步骤
- 移除展开控件
直接删除columns配置里第一个带dt-control类的控制列——这个列就是专门用来渲染展开十字按钮的,删除后控件会完全消失,不会残留多余DOM节点。
注意:删除第一列后,原配置里排序的列索引会左移一位,需要把
order: [[1, 'asc']]改成order: [[0, 'asc']],否则会出现排序错位。
如果暂时不想删除该列(预留后续功能),也可以直接加CSS隐藏控件,效果一致:
.dt-control { display: none !important; }
- 自动展开所有子行(无性能损耗)
利用DataTable的生命周期钩子,只在首次加载、表格重绘时,给还未展开子行的行渲染并展开子行,不会重复操作已展开的行,也不会全量遍历不必要的数据:
- 用
initComplete钩子处理首次ajax加载完成后的所有行 - 用
draw事件处理排序、分页、搜索后重绘的当前页行,仅遍历当前页数据,开销极低 - 每次展开前先判断
row.child.isShown(),完全避免重复DOM操作
修改后的完整代码
$(document).ready(function () { var table = $('#example').DataTable({ ajax: 'static/ajax/data/data.json', columns: [ { data: 'Value1' }, { data: 'Value2' }, { data: 'Value3' }, ], order: [[0, 'asc']], // 列索引对应调整 // 首次加载完成后展开所有子行 initComplete: function () { this.rows().every(function () { if (!this.child.isShown()) { this.child(format(this.data())).show(); $(this.node()).addClass('shown'); } }); } }); // 重绘时自动展开当前页未展开的子行 table.on('draw', function () { table.rows({ page: 'current' }).every(function () { if (!this.child.isShown()) { this.child(format(this.data())).show(); $(this.node()).addClass('shown'); } }); }); // 原有的点击展开/收起事件监听可以直接删除,不需要保留 });
性能说明
这套写法不会产生额外性能损耗:
- 所有展开操作前都做了状态判断,已展开的行不会重复执行DOM渲染
- 分页/排序/搜索场景下仅处理当前显示的行,不会遍历全量数据
- 直接删除控制列比CSS隐藏少渲染一列DOM,渲染开销更低
- 没有额外的事件绑定、定时器等冗余逻辑
内容的提问来源于stack exchange,提问作者TheNerdy97
相关产品推荐
相关产品推荐

