
transition 无法监听 right 变化是因为元素初始 right 是 auto
很多开发者写 transition: right 0.3s,结果动画不触发——根本原因是:侧边菜单默认是隐藏状态,CSS 中常设为 right: -300px,但若 HTML 元素没显式设置 right(比如靠 position: absolute + top/left 定位),浏览器计算出的初始 right 值是 auto,而 auto 到具体像素值之间无法插值,transition 直接失效。
实操建议:
立即学习“前端免费学习笔记(深入)”;
- 确保抽屉容器始终有明确的
right值(哪怕初始为right: -100%或right: -320px),不要依赖auto - 用
transform: translateX()替代right更可靠,因为transform在任何初始状态下都支持过渡 - 如果坚持用
right,需在 JS 切换前强制触发布局,例如读取一次offsetWidth,让浏览器先计算出当前right值再改
抽屉菜单的 show/hide 状态必须由 class 控制,不能只靠 JS 写 style
直接用 element.style.right = '0' 设置内联样式,会导致 transition 被覆盖或中断——CSS 的 !important 或更高优先级规则可能压不住内联样式,且后续状态难以统一管理。
实操建议:
立即学习“前端免费学习笔记(深入)”;
- 定义两个 class:
.drawer--open(right: 0)和.drawer--closed(right: -320px),用 JS 切换 class - transition 规则写在基础类(如
.drawer)上,而非状态类里,避免重复声明 - 加
will-change: transform或transform: translateZ(0)可提升动画帧率,尤其在低端安卓 WebView 中明显
移动端点击穿透和滚动截断必须手动处理
抽屉展开后,背后页面仍可滚动、按钮仍能被点中,这是常见交互破绽。CSS 的 pointer-events: none 和 overflow: hidden 很容易漏配或配错层级。
实操建议:
立即学习“前端免费学习笔记(深入)”;
- 抽屉打开时,给
加 classno-scroll,配合body.no-scroll { overflow: hidden; } - 遮罩层(overlay)必须存在,且
z-index高于抽屉内容但低于抽屉本身,否则点击会穿透到背景 - 遮罩层要加
pointer-events: auto(默认是 auto,但某些 reset.css 会设成 none),确保能拦截点击 - 抽屉内部若含长列表,需单独控制其
overflow-y: auto,别让整个页面跟着动
transitionend 事件监听要防多次触发和伪触发
用 element.addEventListener('transitionend', handler) 监听动画结束,但 transitionend 在任意属性完成时都会触发,包括 opacity、transform、right —— 如果同时过渡多个属性,handler 会被调用多次;更糟的是,某些浏览器(如 Safari 15.4)会在 transition 未真正开始时也抛一次事件。
实操建议:
立即学习“前端免费学习笔记(深入)”;
- 在 handler 里检查
event.propertyName === 'right'或'transform',过滤无关属性 - 加一个开关变量(如
isAnimating),进入 handler 后立即设为false,避免重复执行逻辑 - 更稳妥的做法:不用
transitionend,改用setTimeout延迟执行(时间与 CSS 中transition-duration一致),简单粗暴但稳定










