直接在 table.render 前插入 DOM 不生效,因 Layui 表格异步渲染时会清空容器内容;正确做法是将骨架屏置于表格容器同级,通过 before 或手动控制 visibility/opacity 显隐,并动态同步尺寸以确保对齐。
为什么直接在 table.render 前加 DOM 不生效
layui 的 table.render() 是异步渲染,表格容器(比如 div#demo)在调用前若为空,layui 会自动清空并重写整个区域——你手动插入的骨架屏 dom 很可能被直接删掉。这不是 bug,是设计使然:layui 表格控制权完全交由其内部 render 流程管理。
真正能稳定接管加载态的入口,只有两个:loading 配置项(但只支持布尔值或图标,不支持自定义 HTML),以及 done 回调(仅在渲染完成后触发)。所以得绕过“提前插 DOM”思路,改用 CSS + JS 协同控制显隐。
- 骨架屏必须放在和表格容器同级、且受同一父容器控制的位置,不能塞进表格容器内部
- 用 CSS 控制初始显示,等
table.render()开始请求时再隐藏,成功后不再恢复(由表格自身接管) - 避免监听
ajax请求状态——Layui 封装了 XHR,不暴露原生 promise 或 xhr 对象
用 loading 属性配合自定义 skeleton 容器
核心做法:把骨架屏做成独立 div,和表格容器并列,用 CSS 控制 visibility;通过 before 回调(Layui 2.8+ 支持)或手动模拟 loading 状态来切换。
如果你用的是 Layui 2.8+,直接利用 before 回调:
table.render({
elem: '#demo',
url: '/api/list',
// ...
before: function() {
document.getElementById('skeleton').style.display = 'block';
},
done: function(res, curr, count) {
document.getElementById('skeleton').style.display = 'none';
}
});
如果还是旧版(如 2.7),before 不存在,就得在 render 调用前手动 show skeleton,并在 done 中 hide ——但要注意:Layui 的请求是 lazy 触发的(首次渲染才发),所以得确保 skeleton 在页面就绪时已显示,且不被误删。
- 骨架屏
div#skeleton必须写在表格容器外层,例如:<div class="table-wrapper"> <div id="skeleton">...</div> <table id="demo"></table> </div> - 给
#skeleton加position: absolute和z-index,覆盖在表格区域上,避免布局位移 - 不要用
display: none切换——会导致重排;推荐用visibility: hidden或opacity: 0+pointer-events: none
如何让 skeleton 和表格尺寸严格对齐
骨架屏宽高不对齐,用户一眼就能看出“假”。Layui 表格宽度默认撑满父容器,但高度是内容驱动的。所以 skeleton 的尺寸不能写死,得动态同步。
最稳妥的方式是:监听表格容器宽度变化,并在 done 后读取实际渲染后的表格高度,反向设置 skeleton 高度。
done: function(res, curr, count) {
const tableEl = document.querySelector('#demo + .layui-table');
const skeleton = document.getElementById('skeleton');
if (tableEl) {
skeleton.style.width = tableEl.offsetWidth + 'px';
skeleton.style.height = tableEl.offsetHeight + 'px';
}
skeleton.style.visibility = 'hidden';
}
- 注意:Layui 渲染后生成的
.layui-table是紧跟在table#demo后面的兄弟节点,不是子节点 - 如果表格有固定列(
fixed: true),需额外处理左侧固定列区域的 skeleton 覆盖,否则会出现错位 - 移动端响应式下,建议 skeleton 使用
min-height而非固定 height,避免小屏下内容截断
兼容性与性能注意点
骨架屏本质是视觉过渡,不该增加额外请求或阻塞主流程。Layui 自身不提供骨架组件,所以所有 DOM 和样式都得手写,务必轻量。
- 骨架屏 HTML 最好内联在页面中,避免额外 HTTP 请求;CSS 用最少的选择器,避免影响首屏渲染
- 不要在
done里做复杂计算或 DOM 遍历——它会在每次翻页、重载时执行,容易卡顿 - Layui 2.8 开始支持
autoRender: false,可手动控制渲染时机,适合需要精细控制加载态的场景,但需自行调用table.reload()和table.render() - 如果表格启用了
height固定高度,骨架屏也得设相同 height,并注意滚动条是否遮挡 skeleton 内容
真正难的不是画几根灰色横线,而是让 skeleton 的生命周期和 Layui 表格的异步节奏严丝合缝——稍一错位,用户就会觉得“卡了一下”,而不是“平滑过渡”。











