抖动动画需用CSS keyframes配合class切换实现,通过layer.open()返回的index精准定位弹层并添加layer-shake类,在animationend事件中移除,避免动画堆积与样式干扰。
抖动动画要用 CSS keyframes 配合 class 切换
layui 的 layer.open() 本身不提供抖动效果,必须手动加 css 动画 + js 控制 class。直接在弹层 dom 上用 layer.style 或内联样式写动画会失效,因为 layui 会重置部分样式。正确做法是给弹层容器加自定义 class,再用 css 触发动画。
常见错误是把动画写在 .layui-layer 全局类上,结果所有弹层一起抖——实际应限定作用域,比如只对特定 type 或 id 的弹层生效。
- 先定义
@keyframes shake,偏移量建议用translateX(-4px)和translateX(4px),避免触发重排(用 transform 更高效) - 抖动 class 如
layer-shake应设animation: shake 0.5s ease-in-out,且加animation-iteration-count: 2控制次数 - 动画结束后要手动移除 class,否则连续触发时动画不会重复播放(CSS 动画不会自动重置)
如何精准定位到目标弹层并添加抖动 class
Layui 弹层打开后,会在 body 末尾追加一个 .layui-layer 元素,但多个弹层共存时,不能靠 document.querySelector('.layui-layer') 直接取最后一个——可能被其他 layer 干扰。稳妥方式是利用 layer.open() 返回的 index 值,配合 layer.getChildFrame() 或直接查 data-index 属性。
实操建议:
- 调用
layer.open()后保存返回的index,例如let idx = layer.open({...}) - 用
document.querySelector('[lay-id="' + idx + '"]')或document.querySelector('.layui-layer[times="' + idx + '"]')定位(注意:不同版本属性名略有差异,v2.8+ 推荐用lay-id) - 拿到 DOM 后,用
el.classList.add('layer-shake'),并在animationend事件里移除
抖动时机:该在什么环节触发
不是所有场景都适合一打开就抖——比如表单校验失败才需要提醒,而成功提示不需要。所以抖动逻辑不应写死在 open 调用里,而应封装成独立函数,按需调用。
典型使用场景:
- 表单提交后服务端返回 error,此时调用抖动函数
- 用户点击“确定”但必填项为空,用
layer.msg('请填写XX', {icon:2})同时触发主弹层抖动 - 避免在
success回调里直接操作 DOM,因为此时弹层可能尚未完全渲染完成;建议用setTimeout(..., 10)或监听layer.ready()(需自行 patch)
兼容性与性能注意点
IE10+ 支持 @keyframes,但部分安卓低版本 WebView 对 transform 动画支持不稳定。如果必须兼容,可降级为 margin-left,但会触发 layout,性能略差。
容易被忽略的细节:
- 抖动过程中用户若点击遮罩层关闭弹层,需在
cancel或end回调里清理动画 class,防止残留 - 同一弹层多次抖动时,若前一次动画未结束就再次 addClass,会导致动画队列堆积;应加锁机制,如用
el.dataset.isShaking === 'true'拦截 - Layui v2.8 后默认启用硬件加速,但抖动动画若没加
transform: translateZ(0),某些设备仍可能卡顿











