IntersectionObserver 是触发入场动画最稳最轻量的方案,它异步回调、自动节流、不卡顿不误判,需在元素挂载后立即 observe,配合 opacity:0/translateY() 初始态和 animation-fill-mode:forwards 防闪防回退。
用触发入场动画是当前最稳、最轻量的方案,比手写事件监听靠谱得多——它不卡顿、不误判、自动节流,而且浏览器原生支持。
为什么不能直接用 CSS
加载就播
CSS 的
+
一加载就执行,和用户是否看见元素完全无关。你看到“闪一下再动”或“滚动到一半才开始”,基本都是这个原因。入场动画必须等元素真正进入视口才启动,而
就是干这事的:只管“有没有进”,不管“滚了多少”。
别在
里反复调用
—— 主线程压力大,低端机明显掉帧
是异步回调,浏览器内部优化过,iOS Safari 12.1+、Chrome 51+、Firefox 55+ 都已稳定支持
IE 完全不支持,如需兼容,得用 polyfill 或降级为 scroll 监听(但仅限兜底)
初始化时最容易漏的两件事
初始化晚了或选错元素,会导致首次进入视口时不触发——尤其在 SPA 或动态渲染内容时特别明显。
必须在目标元素已经挂载到 DOM 后立刻调用
,不能等
或
才开始
要用
,不是
—— 后者只返回第一个匹配元素,其余全被忽略
如果元素是 JS 动态插入的(比如 React 渲染后),得在插入后立即 observe,不能靠一次性遍历
动画类怎么写才不闪、不跳、不回退
初始状态必须「占位但不可见」,否则会先渲染出原始样式,再突兀跳到动画起点,视觉上就是“闪一下”。
使用HTML,CSS,JavaScript开发Android应用程序 英文文字pdf版附源文件
如果你了解HTML,CSS和JavaScript,您已经拥有所需的工具开发Android应用程序。本动手本书展示了如何使用这些开源web标准设计和建造,可适应任何Android设备的应用程序 - 无需使用Java。您将学习如何创建一个在您选择的平台的Android友好的网络应用程序,然后转换与自由PhoneGap框架到一个原生的Android应用程序。了解为什么设备无关的移动应用是未来的潮流,并开始构建应用程序,提供更
下载
立即学习
“
前端免费学习笔记(深入)
”;
推荐组合:
+
+
(可选)
千万别用
做初始隐藏——它会让元素脱离文档流,导致后续布局重排、文字抖动
动画结束要停在最后一帧,必须加
或在 class 里写
,否则动画播完瞬间回退到初始态
避免在动画中改
、
、
、
等触发布局的属性,它们无法 GPU 加速
怎么防止同一元素反复触发、重复播放
默认不记忆状态,元素进出多次,回调就执行多次。你得自己控制“只播一次”。
最简做法:在回调里加个判断
,然后加类、再调
别依赖
事件来清理——切 Tab、快速滚动、系统休眠都可能导致它不触发
如果需要“退出后再进入重播”,就去掉
,改用类名切换逻辑(比如
和
之间来回切)
注意:一旦
,该元素就不会再被监听,除非你手动重新
真正容易被忽略的是 threshold 和 rootMargin 的配合使用——比如想让动画提前一点触发,设
不够,还得加
把触发区往上扩,否则首屏元素可能直接“跳过”动画。这个细节在移动端尤其关键。
IntersectionObserverscrollanimation@keyframesanimationIntersectionObserverwindow.addEventListener('scroll', ...)getBoundingClientRect()IntersectionObserverIntersectionObserverobserver.observe(el)DOMContentLoadedwindow.onloaddocument.querySelectorAll('.js-animate')document.querySelector('.js-animate')opacity: 0transform: translateY(20px)visibility: hiddendisplay: noneanimation-fill-mode: forwardsforwardsheightwidthtopleftIntersectionObserverif (el.classList.contains('animate-in')) return;observer.unobserve(el)animationendunobserveanimate-in activeanimate-inunobserveobservethreshold: 0.1rootMargin: '0px 0px -50px 0px'