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

如何将计数动画代码封装为可复用函数并在IntersectionObserver中调用

封装数字计数与SVG描边动画函数并结合IntersectionObserver使用

1. 封装可复用动画函数

把原逻辑封装成独立函数,将依赖的元素集合作为参数传入,避免全局变量污染,同时增加重置逻辑确保动画可重复触发:

function startCountAndSvgAnimation(numbers, svgElements) {
  // 初始化每个元素的计数器和定时器
  const counters = [];
  const intervals = [];

  // 先重置所有元素状态(避免重复触发时状态混乱)
  numbers.forEach((number, index) => {
    counters[index] = 0;
    number.textContent = "0%";
    // 重置SVG描边初始状态
    svgElements[index].style.strokeDashoffset = 472;
    // 清除可能存在的旧定时器
    if (intervals[index]) {
      clearInterval(intervals[index]);
    }
  });

  // 启动动画
  numbers.forEach((number, index) => {
    const targetNum = parseInt(number.dataset.num);
    intervals[index] = setInterval(() => {
      if (counters[index] === targetNum) {
        clearInterval(intervals[index]);
      } else {
        counters[index] += 1;
        number.textContent = `${counters[index]}%`;
        // 计算SVG描边偏移量
        svgElements[index].style.strokeDashoffset = Math.floor(472 - 440 * (targetNum / 100));
      }
    }, 20);
  });
}

// 可选:重置函数,用于元素离开视口时恢复初始状态
function resetCountAndSvgAnimation(numbers, svgElements) {
  numbers.forEach((number, index) => {
    number.textContent = "0%";
    svgElements[index].style.strokeDashoffset = 472;
    // 清除定时器
    if (window.intervals?.[index]) {
      clearInterval(window.intervals[index]);
    }
  });
}

2. 结合IntersectionObserver调用

修改Observer逻辑,在元素进入视口时启动动画,离开时按需重置状态:

// 替换成你的实际元素选择器
const numbers = document.querySelectorAll('.number-element');
const svgEl = document.querySelectorAll('.svg-stroke-element');

const animateObserver = new IntersectionObserver((entries) => {
  entries.forEach(entry => {
    if (entry.isIntersecting) {
      // 元素进入视口,启动动画
      startCountAndSvgAnimation(numbers, svgEl);
      // 若只需触发一次,可在此调用unobserve停止观测
      // animateObserver.unobserve(entry.target);
    } else {
      // 元素离开视口,重置状态(按需启用)
      resetCountAndSvgAnimation(numbers, svgEl);
    }
  });
});

animateObserver.observe(test);

关键优化点

  • 消除全局依赖:将计数器、定时器放在函数内部,通过参数传递元素集合
  • 支持重复触发:添加重置逻辑,确保元素再次进入视口时动画能正常启动
  • 逻辑拆分:将启动和重置拆分为独立函数,提升代码可维护性

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.11 10:00:24