必须用 IntersectionObserver 检测元素进入视口再动态加类触发动画,因其异步低开销、自动节流且兼容性好;初始状态需设 opacity:0 + transform:translateY(20px) + visibility:hidden 占位防跳变;动画后应 unobserve 或标记避免重复触发。

怎么让元素进入视口时才触发动画
直接用 CSS 的 @keyframes + animation 是不行的——它一加载就播,和是否看见无关。必须靠 JavaScript 检测滚动位置,再动态加类触发。核心是 IntersectionObserver,不是 scroll 事件监听。
常见错误是手动写 window.addEventListener('scroll', ...),性能差、易卡顿、频繁重算;而 IntersectionObserver 是浏览器原生 API,异步回调、低开销、自动节流。
- 只观察目标元素是否进入(或离开)视口,不关心具体滚动值
- 支持配置
threshold:比如设为[0.1]表示元素 10% 进入视口就触发 - 兼容性足够好:Chrome 51+、Firefox 55+、Safari 12.1+、Edge 79+,基本可放心用
入场动画类该怎么写才不闪、不跳
关键在初始状态必须「不可见但已占位」,否则元素会先渲染再动画,造成视觉跳变。最稳妥写法是:opacity: 0 + transform: translateY(20px) + visibility: hidden(可选),然后用 transition 或 @keyframes 过渡到可见态。
别用 display: none 做隐藏——它会脱离文档流,导致后续布局重排;也别只靠 opacity: 0 而不配 transform,因为 opacity 变化若没硬件加速,可能糊帧。
- 推荐组合:
opacity控制显隐,transform控制位移/缩放,两者都支持 GPU 加速 - 避免动画中修改
width/height/top/left等触发布局的属性 - 如果用
@keyframes,记得加forwards,否则动画结束瞬间会回退到初始样式
怎么防止滚动中反复触发同一动画
IntersectionObserver 默认不会去重,同一个元素进进出出多次,就会多次回调。你得在回调里手动控制:一旦动画播过,就取消观察,或打上标记不再处理。
最简方案是在回调中检查元素是否已有 animate-in 类,有就 return;没有就加类、然后调用 observer.unobserve(el)。
- 不要依赖
animationend事件来移除类——它可能不触发(比如用户切 Tab) - 如果要支持「退出视口再进入时重播」,就把
unobserve去掉,改用类名切换逻辑控制 - 注意:
unobserve后该元素不会再被观察,除非重新observe
移动端滚动入场动画卡顿怎么办
本质是渲染管线压力大,尤其低端 Android 设备。优先级最高的优化是启用硬件加速,并减少主线程负担。
给动画元素加 will-change: transform, opacity 是有效手段,但别滥用——只对真正会动的元素加;同时确保父容器没有 overflow: hidden 之类限制合成层的样式。
- 动画属性严格限定在
transform和opacity上,这两者走的是合成器线程 - 避免在
IntersectionObserver回调里做 DOM 批量操作或复杂计算 - 如果页面滚动很慢,先检查是否有其他 JS 阻塞主线程,或是否开启了
prefers-reduced-motion
真正难搞的是嵌套滚动容器(比如 div[style="overflow-y: auto"] 内的内容),这时 IntersectionObserver 默认观察的是 viewport,不是父容器。得手动传 root 参数指定滚动上下文。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











