如何实现GSAP ScrollTrigger的onEnter回调仅执行一次
问题描述
- 业务场景:使用GSAP动画库实现网站滚动动画,为页面底部类名为
.c的绿色方块"C"绑定ScrollTrigger的onEnter回调,配置为元素进入视口时触发test函数,在控制台输出日志。 - 异常表现:用户向上滚动页面后,再次向下滚动回到触发位置时,绑定的回调函数会重复执行。
- 需求目标:无论用户上下滚动多少次经过该触发点,回调函数都仅运行1次,此前在全网范围(含GSAP官方论坛)检索未找到有效实现方案。
原有复现代码
JavaScript 逻辑
gsap.registerPlugin(ScrollTrigger); gsap.to(".c",{ scrollTrigger:{ trigger trigger:".c", onEnter:test, start:"top center", markers:true, }, x:400, rotation:300, immediateRender: true, duration:3 }) function test(){ console.log("I am entered") }
CSS 样式
.sc-div{ height:100px; width:100px; display: flex; align-items:center; justify-content:center; } .a{ background:red; margin-top:50px; } .b{ background: yellow; } .c{ background: green; margin-bottom: 400px; } .mt{ margin-top:500px }
HTML 结构
<script src="https://cdnjs.cloudflare.com/ajax/libs/gsap/3.10.4/ScrollTrigger.min.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/gsap/3.10.4/gsap.min.js"></script> <div class="a sc-div">A</div> <div class="b sc-div mt">B</div> <div class="c sc-div mt">C</div>
实现方案
根据业务场景二选一即可:
方案1:使用ScrollTrigger内置配置(改动最小)
直接在scrollTrigger配置对象中添加once: true。该配置生效后,ScrollTrigger第一次触发完成会自动销毁自身实例,后续滚动经过触发点不会再触发任何回调,关联的入场动画也仅会在首次进入时播放一次,完全适配动画和回调都只需要执行一次的场景。
修改后的核心JS代码:gsap.registerPlugin(ScrollTrigger); gsap.to(".c",{ scrollTrigger:{ trigger:".c", onEnter:test, start:"top center", markers:true, once: true // 新增该行配置即可 }, x:400, rotation:300, immediateRender: true, duration:3 }) function test(){ console.log("I am entered") }方案2:自定义执行标记位(灵活性更高)
如果需要保留ScrollTrigger的其他回调逻辑(比如onLeave、onEnterBack等),仅要求onEnter绑定的test函数单次执行,用状态标记的方式实现即可:定义一个布尔变量记录回调是否已经执行过,每次进入触发点先判断状态,已经执行过就直接终止逻辑,否则执行业务代码后将标记更新为已执行状态。
示例代码:gsap.registerPlugin(ScrollTrigger); // 定义回调执行状态标记 let hasTestExecuted = false; gsap.to(".c",{ scrollTrigger:{ trigger:".c", onEnter: () => { if(hasTestExecuted) return; test(); hasTestExecuted = true; }, start:"top center", markers:true, }, x:400, rotation:300, immediateRender: true, duration:3 }) function test(){ console.log("I am entered") }
内容的提问来源于stack exchange,提问作者Shayan Kanwal
相关产品推荐
相关产品推荐

