You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何实现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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.28 01:21:33