骨架HTML必须在table.render()前手动插入#demo .layui-table-body内,行数5~8、每td含height:42px的layui-skeleton-item,配合table-layout:fixed及width:100%等CSS确保尺寸一致,并通过before/done回调精准控制显隐。
表格渲染前插入骨架 HTML 结构
必须在 table.render() 执行前手动写入骨架 dom,否则骨架会漏掉或被覆盖。layui 不会在 data 加载完成前自动占位,空 data: [] 只渲染空表,不是骨架。
推荐做法:先清空容器,再插入一组与真实列数、行高一致的 <tr><td><div class="layui-skeleton-item"></div></td></tr> —— 行数建议 5~8 行,避免滚动条突变。
- 不要用
table.on('request')插入,它只在 url 模式下触发,且时机晚于 DOM 初始化 - 骨架元素必须放在
#demo .layui-table-body内部,否则宽度无法继承列宽计算结果 - 每列骨架
<div>建议加style="height: 42px;"(匹配 layui 默认行高),避免高度跳变
骨架样式要匹配真实表格尺寸
骨架闪动的主因是尺寸不一致:列宽撑开、行高抖动、圆角/边距错位。Layui 表格列宽由 JS 动态注入 style,骨架必须靠 CSS 继承或复刻这套逻辑。
关键 CSS 规则:
.layui-skeleton-item {
background: linear-gradient(90deg, #f0f0f0 25%, #e0e0e0 50%, #f0f0f0 75%);
background-size: 200% 100%;
animation: skeleton-loading 1.4s ease-in-out infinite;
border-radius: 2px;
width: 100%;
height: 42px;
}
@keyframes skeleton-loading {
0% { background-position: -200% 0; }
100% { background-position: 200% 0; }
}- 禁用
width固定值,用width: 100%让骨架随列宽自适应 - IE11 下必须给
<table>加style="table-layout: fixed;",否则骨架列宽会错乱 - 如果某列用了
minWidth(如minWidth: 150),骨架对应<td>也得设相同最小宽度
before / done 回调控制显隐时机
before 和 done 是唯二能精准对齐表格生命周期的钩子。别依赖 success 或 complete,它们属于 AJAX 层,和表格 DOM 渲染节奏不同步。
典型写法:
table.render({
elem: '#demo',
cols: [[/* ... */]],
url: '/api/list',
before: function() {
// 确保骨架已存在,否则重插
const body = document.querySelector('#demo .layui-table-body');
if (!body.querySelector('.layui-skeleton-item')) {
body.innerHTML = generateSkeletonHTML(6); // 自定义生成函数
}
},
done: function(res, curr, count) {
// 数据就绪后,骨架自动被 render 覆盖,无需手动 remove
// 但若 reload 时想保留骨架,就得在 before 里重插
}
});-
before里不要做异步操作(如$.get),它必须同步返回 -
done中不建议操作骨架 DOM,因为 Layui 已用新 HTML 替换整个<tbody> - 如果用了
page: true,骨架只需插一次;分页切换时,before仍会触发,可复用同一套逻辑
reload 时骨架容易失效
调用 table.reload() 时,Layui 默认不清空容器就重绘,旧骨架可能残留,也可能被新 DOM 覆盖不干净,导致半截骨架 + 半截真实数据。
稳妥解法:每次 reload 前手动清理并重插骨架。
- 在
reload调用前执行document.querySelector('#demo .layui-table-body').innerHTML = '' - 紧接着调用
table.reload({ ..., done: function() { ... } }),确保before有机会重插 - 避免在
done里用$().html()替换整个表格容器,这会破坏 Layui 的事件绑定和内部状态
真正难的不是写骨架,而是让它的高度、宽度、动画节奏和表格每一帧渲染严丝合缝——差 1px 或 10ms,用户就会觉得“卡了一下”。


















