footerCallback 是表格页脚渲染完成后触发的回调,用于动态计算并填充当前页数据的统计值,仅执行一次且依赖 data 参数进行可靠计算。
layui table 的 footerCallback 是什么作用
它是在表格底部(tfoot)渲染完成后触发的回调,专门用来动态计算并填充页脚数据。不是用来初始化表格,也不是每行渲染都调用——只在当前页数据加载完、页脚 dom 生成后执行一次。
关键点:它接收四个参数:data(当前页原始数据数组)、cols(列配置)、count(当前页条数)、lenght(实际渲染行数,含合计行时可能不同)。其中 data 是你做统计的唯一可靠来源。
- 必须配合
done回调或直接在render后手动调用table.render()才能生效 - 如果用了
page: false(不分页),data就是全部数据;分页状态下才是当前页数据 - 不能在
init阶段就写死数值,必须等data真实可用后再算
怎么用 footerCallback 算当前页某列总和
假设你要统计“price”字段(对应列 field: 'price')的当前页总和,并显示在页脚第二列:
table.render({
elem: '#demo',
url: '/api/list',
cols: [[
{field: 'id', title: 'ID'},
{field: 'price', title: '金额', totalRowText: '合计:'}
]],
page: true,
footerCallback: function(data, cols, count, length){
let sum = 0;
data.forEach(function(item){
sum += parseFloat(item.price) || 0;
});
// 找到 price 列的 td,填入结果(注意索引从 0 开始)
$(this.elem).next('.layui-table-box').find('tfoot td:eq(1)').html('合计:' + sum.toFixed(2));
}
});
-
data是当前页的 JSON 数组,不是 DOM 行,所以别用$('tr')去遍历 - 务必用
parseFloat()或Number()转类型,否则字符串相加会变成拼接(如 "1"+"2" → "12") -
td:eq(1)中的1对应的是第二列(索引从 0 开始),要和cols中定义的顺序严格一致 - 如果列用了
templet渲染,item.price仍可用——只要原始数据里有这个字段
为什么页脚总和没更新或显示 NaN
最常见原因是数据字段缺失或格式异常,导致 parseFloat 返回 NaN,后续累加全崩。
- 后端返回的 price 字段可能是
null、undefined、空字符串或带单位(如 "¥100"),直接parseFloat('¥100')得到 100 没问题,但parseFloat('')或parseFloat(null)是NaN - 解决办法统一兜底:
sum += (parseFloat(item.price) || 0) - 如果用了服务端分页,确认接口返回的
data确实是当前页数据(有些后端把total放在顶层,混淆了分页逻辑) - 检查是否启用了
loading: true但没正确关闭,导致footerCallback在 DOM 未就绪时执行
想同时统计多列怎么办
别堆多个 eq(),用循环更稳:
footerCallback: function(data, cols, count, length){
const sums = {price: 0, qty: 0};
data.forEach(function(item){
sums.price += parseFloat(item.price) || 0;
sums.qty += parseInt(item.qty) || 0;
});
const $tfoot = $(this.elem).next('.layui-table-box').find('tfoot td');
$tfoot.eq(1).html('金额合计:' + sums.price.toFixed(2));
$tfoot.eq(2).html('数量合计:' + sums.qty);
}
注意:$tfoot.eq(n) 的 n 必须和列定义顺序完全对齐。如果中间加了隐藏列或用了 hide: true,eq() 索引也要相应调整——页脚 td 数量和 visible 列数一致,不包含隐藏列。
复杂点在于列顺序和索引映射容易错,尤其是多人协作改表结构时。建议把列 field 和页脚位置写成配置对象,而不是硬编码 eq(1)、eq(2)。


















