抽屉导航必须用 transform: translatex() 实现位移,避免 left 触发重排;遮罩 pointer-events 需动态控制,打开时 auto、关闭动画结束后才设 none;移动端拖拽需 preventdefault() 和 passive: false,并用 clientx 计算位移。

抽屉导航的 transform 位移必须用 translateX 而不是 left
直接改 left 属性做滑动,动画会触发重排(reflow),卡顿明显;transform: translateX() 走 GPU 合成层,性能好得多。移动端尤其明显。
常见错误是给抽屉容器设 position: absolute 后用 left: -100% 隐藏,再用 transition: left 0.3s —— 这样动画一卡一卡的,尤其在 iOS Safari 上。
- 抽屉容器必须设
transform: translateX(-100%)初始隐藏,展开时改为translateX(0) - 过渡动画只写
transition: transform 0.3s ease,别加其他属性 - 确保父容器有
overflow: hidden,否则抽屉滑出时内容会溢出可见
遮罩层(overlay)的 pointer-events 必须动态控制
点击遮罩关闭抽屉时,如果遮罩一直可点击,会导致快速连点多次触发关闭逻辑;如果始终不可点击,又无法响应第一次点击。关键在于状态切换时机。
- 抽屉打开时,遮罩要设
pointer-events: auto - 抽屉关闭动画结束前,必须保持
pointer-events: auto,否则动画中途点不了 - 关闭动画完成(监听
transitionend或用setTimeout延迟)后,才设pointer-events: none - 别依赖
opacity: 0判断是否隐藏——它不影响点击穿透,pointer-events才是开关
移动端 touch 拖拽关闭需要 preventDefault 和 passive:false
想让用户手指拖动抽屉关闭(类似原生 App),直接监听 touchmove 不行:iOS Safari 默认会触发页面滚动,拖拽失效。
- 给抽屉容器绑定
touchstart时,必须调用event.preventDefault() -
touchmove监听器要传{ passive: false },否则浏览器忽略preventDefault - 计算位移用
event.touches[0].clientX,别用pageX(可能受缩放影响) - 松手后判断拖动距离是否超过阈值(比如 50px),决定是回弹还是关闭
Vue/React 中 toggle 状态与 class 切换的时序容易错
状态变量(如 isDrawerOpen)更新后立即切 class,但 DOM 还没重绘,getBoundingClientRect() 或动画起始位置可能拿不准。
- React 里用
useEffect+useState,状态更新后等一次requestAnimationFrame再操作 DOM - Vue 里别在
v-if切换后立刻读取元素尺寸,改用$nextTick - 不要靠 class 名判断当前状态(比如检查是否有
open类),统一以数据状态为准,避免 class 和 state 不同步 - 动画结束回调里清理状态,而不是靠 CSS
transitionend的 event.target 判断——多个元素可能共用同一事件监听器
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











