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

如何防止滚动触发的GIF序列播放递归函数被重复调用

问题原因

  1. 滚动事件触发频率极高,每次滚动只要检测到gifIsPlaying为false就会重新调用playGifService(0),相当于每次符合条件就新开一条定时器执行链,多条定时器并行就会出现重复运行的问题
  2. 原视口检测逻辑不严谨:仅判断.service-list的offset.top小于窗口高度,没有判断元素是否完全离开视口下方,就算元素已经被滚到视野外,定时器还会继续执行
  3. 没有做定时器清除机制,之前启动的定时器任务没有被销毁,新的任务又叠加运行

修复方案

第一步:新增全局变量存储定时器和运行状态

var gifTimer = null;
var gifSequenceRunning = false; // 标记整个序列是否已经启动
var currentGifIndex = 0; // 保存当前播放到的索引,可配置离开视口再回来是续播还是从头播放

第二步:封装准确的视口检测函数

function isServiceListInViewport() {
    const $list = $('.service-list');
    if (!$list.length) return false;
    const rect = $list[0].getBoundingClientRect();
    // 只要元素有部分出现在视口内就返回true
    return rect.top < window.innerHeight && rect.bottom > 0;
}

第三步:重写播放逻辑,增加定时器清除处理

function playGifService() {
    // 不在视口内就停止序列,重置状态
    if (!isServiceListInViewport()) {
        clearTimeout(gifTimer);
        gifSequenceRunning = false;
        // 如果需要离开再回来从头播放就放开下面这行,不需要就注释保持续播逻辑
        // currentGifIndex = 0;
        return;
    }
    gifSequenceRunning = true;
    // 处理上一个索引的资源隐藏,当前索引的资源显示
    const prevIndex = (currentGifIndex - 1 + 4) % 4;
    $(`#service-item-${prevIndex} .service-item-gif`).hide();
    $(`#service-item-${prevIndex} .service-item-png`).show();
    $(`#service-item-${currentGifIndex} .service-item-gif`).show();
    $(`#service-item-${currentGifIndex} .service-item-png`).hide();
    // 索引自增
    currentGifIndex = (currentGifIndex + 1) % 4;
    // 存储定时器ID方便后续清除
    gifTimer = setTimeout(playGifService, 3000);
}

第四步:修改滚动事件触发逻辑

scroller = new LocomotiveScroll();
scroller.on("scroll", function(t, e) {
    // 只有当元素在视口内,且序列还没启动的时候才启动,避免重复创建执行链
    if (isServiceListInViewport() && !gifSequenceRunning) {
        playGifService();
    }
});

可选优化:页面初始化时检测一次

避免元素默认就在首屏视口内,没触发滚动事件导致不播放:

$(document).ready(function() {
    if (isServiceListInViewport() && !gifSequenceRunning) {
        playGifService();
    }
});

内容的提问来源于stack exchange,提问作者Henry Gunawan

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.25 13:15:02