5 分钟搞懂 layui layer:从 3 行代码弹层到多弹层协同实战
【免费下载链接】layui一套遵循浏览器原生态开发模式的 Web UI 组件库。项目地址: https://gitcode.com/GitHub_Trending/la/layui
做项目第一年被要求"弹个确认框",我直接用了原生 alert,被打回来三次才换成 layui layer。layer 是 layui 组件库内置的通用弹层组件,覆盖 dialog、page、iframe、loading、tips 五种类型,3 行代码弹一个确认框,再配几个参数就能换皮、换动画、换弹出位置。
3 行代码出第一个弹层
别一上来就研究open的全部参数,业务里 90% 的"出个提示"场景,用layer.msg和layer.confirm两个快捷方法就够了:
layui.use('layer', () => { const layer = layui.layer; // 3 秒后自动消失,无遮罩不挡页面 layer.msg('保存成功'); // 确认框:点确定才执行回调 layer.confirm('确定删除这条记录吗?', (index) => { layer.close(index); // 执行完删除请求再关掉 }); });参数只记三个:time是自动关闭的秒数,0 表示不自动关;icon是图标序号,1 成功、2 错误;shade是遮罩,false就是不要那层灰色。其余配置用到时再查。
换皮、动效、嵌页面
定制统一走layer.open这个总入口,type取值:0 对话、1 HTML 内容、2 iframe、3 加载层、4 贴士层。"换皮"和"嵌页面"的区别,其实就是三行配置的差异:
// 换皮:主题 + 位置 + 动画 layer.open({ content: '<div style="padding:15px">自定义内容</div>', title: '自定义弹层', skin: 'layer-my-skin', // 自定义类名,样式自己写在 CSS 里 area: ['500px', 'auto'], offset: 'rt', // 右上角,还支持 't' / 'r' / 'b' / 'l' / 'auto' anim: 5, // 0~6 六种进场动画,也支持 slideLeft 这类命名动画 }); // 嵌页面:content 直接放 URL,type: 2 即 iframe layer.open({ type: 2, title: '订单详情', area: ['800px', '600px'], content: '/order/detail.html', });offset不止四边,lt、rb八个方位都认,坐标换算逻辑在 layer 源码 的ready.updatePosition里。想整套换肤就去 layer.css 加自己的类名,别动内置类,升级时会还你一笔账。
多弹层协同:关谁、怎么关、关不掉会怎样
结论先行:每次layer.open都返回一个index数字,所有关闭动作都针对它,返回值存变量,不要硬编码也不要猜。
// 请求前拉一个 loading 层 const loadIndex = layer.load(1, { shade: [0.1, '#000'] }); // 请求回来关掉它 fetchData().then(() => layer.close(loadIndex)); // 按类型关:只关最近的 loading 层 layer.closeLast('loading'); // 按类型一键清空所有对话层 layer.closeAll('dialog');三个 API 的分工:close(index)关指定层;closeLast(type)关该类型里最近打开的一个;closeAll(type)关该类型全部。后两个按类型匹配,就算你没存 index 也不会误伤别人。而"关不掉"的代价是实打实的:弹层 DOM 和事件监听一直挂在文档里,loading 层的遮罩默认透明度只有 0.01 但照样拦截所有点击,用户会以为页面卡死了。所以铁律是——凡是有异步操作的弹层,把close写进 finally。
四个高频坑与一行修复
弹层被页面固定导航栏挡住。现象:弹层弹出来却被导航条盖住。根因:layer 默认 zIndex 是 19891014 且随新弹层自增,但你页面里自定义的高 z-index 元素可能更狠。修复:success回调里layer.setTop(layero),或 open 时显式传zIndex: 99999。
遮罩没了页面却滚不动。现象:弹层已关,body 滚动条消失。根因:layer 打开时把 html 的 overflow 设为 hidden,正常关闭才会还原。修复:别用 jQuery 手动 remove 弹层 DOM,一律layer.close(index)。
接口报错后 loading 遮罩常驻。现象:请求 500 之后半透明遮罩一直糊在页面上。根因:只在成功分支写了关闭。修复:.catch(() => layer.close(loadIndex))。
iframe 弹层里取不到内部输入框。现象:type: 2嵌的页面,父文档里$('#xx')查无此元素。根因:iframe 是独立文档,根本不在父页面 DOM 树里。修复:用内置的layer.getChildFrame('#xx', index)取子帧元素。
另外要"仿系统输入框"那种表单弹层时,直接layer.prompt,别自己拼 input 加回调。
延伸
想看完整流程,layer 源码 从内部 Class 到外部 API 全在一个文件里;想边点边看效果,layer.html 是官方示例页。核心 API 就这些,剩下的靠手熟。
【免费下载链接】layui一套遵循浏览器原生态开发模式的 Web UI 组件库。项目地址: https://gitcode.com/GitHub_Trending/la/layui
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考