为何我的IntersectionObserver与CSS动画无法正常工作?
解决fullpage.js结合动画触发的问题
问题根源
- fullpage.js的滚动通过修改容器transform实现,并非原生滚动,导致IntersectionObserver无法准确监听section的可见状态
- 你将动画绑定在了section元素上,但实际要动画的是内部的
.square - 直接设置
animation: none无法彻底重置动画状态,需配合初始样式还原
修正方案
改用fullpage.js自带的回调函数监听section的进入与离开,通过添加/移除CSS类控制动画,适配fullpage的滚动机制:
修正后的HTML
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Document</title> <link rel="stylesheet" href="style.css"> <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/fullPage.js/4.0.11/fullpage.min.css"> </head> <body> <div id="fullpage"> <div class="section one">Section One </div> <div class="section two"> Section two <div class="square"></div> </div> <div class="section three">Section Three</div> <div class="section four">Section Four</div> </div> <script src="https://cdnjs.cloudflare.com/ajax/libs/fullPage.js/4.0.11/fullpage.min.js"></script> <script src="script.js"></script> </body> </html>
修正后的CSS
.section { height: 100vh; width: 100vw; display: flex; align-items: center; justify-content: center; } .section.one { background-color: rgb(6, 245, 245); } .section.two { background-color: rgb(0, 149, 255); } .section.three { background-color: rgb(112, 46, 46); } .section.four { background-color: rgb(157, 115, 160); } .square { width: 200px; height: 200px; border-radius: 20px; background: orange; /* 初始状态与动画起始帧保持一致 */ transform: scale(0, 0.025); } /* 通过类控制动画触发 */ .square.animate { animation: square-animation 2s forwards ease-out; } @keyframes square-animation { 0% { transform: scale(0, 0.025); } 50% { transform: scale(1, 0.025); } }
修正后的JS
new fullpage('#fullpage', { autoScrolling: true, navigation: true, // 进入section时触发动画 afterLoad: function(origin, destination) { if(destination.index === 1) { document.querySelector('.square').classList.add('animate'); } }, // 离开section时重置动画 onLeave: function(origin) { if(origin.index === 1) { const square = document.querySelector('.square'); square.classList.remove('animate'); // 强制触发浏览器重绘,确保样式重置生效 void square.offsetWidth; } } })
关键说明
- 用fullpage的
afterLoad和onLeave回调精准监听section切换,避免IntersectionObserver与fullpage滚动机制的冲突 - 通过CSS类控制动画,比直接操作style更易维护,也能更好地重置状态
void square.offsetWidth强制浏览器重绘,解决移除类后动画不重置的问题- 给
.square设置初始transform,保证未动画时的状态与动画起始帧一致
内容的提问来源于stack exchange,提问作者Alex
相关产品推荐
相关产品推荐

