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

实现滚动到指定Div时启动JS数字计数效果求助

实现滚动到目标元素时启动数字滚动计数效果

首先得指出你原来代码里的几个关键问题:

  • setInterval的时间参数是毫秒,你写的0.00001相当于0,浏览器会疯狂执行回调,直接导致页面卡顿,得改成合理的数值(比如16ms,接近浏览器的帧刷新间隔)
  • 没有做「元素是否进入视口」的判断,也没标记计数是否已执行,所以页面一加载计数就自动跑起来了

下面是完整的修复方案,一步步来:

1. 封装可复用的计数函数

先写一个通用的计数函数,支持自定义目标数值、元素ID,还能控制计数的平滑度:

// 计数函数:参数分别是元素ID、目标数值、可选的总持续时间(默认2000ms)
function animateCount(elementId, target, duration = 2000) {
  const element = document.getElementById(elementId);
  if (!element) return;
  
  let current = 0;
  // 计算每一步的增量,基于浏览器帧间隔(约16ms)保证平滑
  const step = target / (duration / 16);
  const timer = setInterval(() => {
    current += step;
    // 最后一步直接设为目标值,避免小数或超出
    if (current >= target) {
      current = target;
      clearInterval(timer);
    }
    // 取整显示,保证数字是整数
    element.textContent = Math.floor(current);
  }, 16);
}

2. 检测元素是否进入视口

写一个工具函数,判断目标div是否滚动到了用户可见的区域:

function isElementInViewport(el) {
  const rect = el.getBoundingClientRect();
  return (
    rect.top <= window.innerHeight &&
    rect.bottom >= 0
  );
}

3. 滚动监听与触发逻辑

添加滚动事件监听,只有当目标div进入视口且计数未执行过时,才启动所有计数:

// 标记计数是否已执行,避免滚动时重复触发
let hasCounted = false;
const targetDiv = document.getElementById('sumtxt');

function handleScroll() {
  if (!hasCounted && isElementInViewport(targetDiv)) {
    // 启动各个数值的计数动画
    animateCount('sabeghe', 30);
    animateCount('moshtari', 3200);
    animateCount('projhe', 4600);
    animateCount('govahiname', 29);
    // 标记为已执行
    hasCounted = true;
    // 可选:计数启动后移除滚动监听,减少性能消耗
    window.removeEventListener('scroll', handleScroll);
  }
}

// 添加滚动监听
window.addEventListener('scroll', handleScroll);
// 页面加载时先检查一次(如果元素一开始就在视口内,直接触发)
handleScroll();

4. 修改后的HTML

去掉原来的onmouseover属性(如果不需要鼠标悬停触发的话),初始数值设为0更符合需求:

<div class="container text-center d-inline" id="sumtxt">
  <strong>بیش از <span id="sabeghe">0</span> سال سابقه</strong>
  <div class="pt-3 pb-3 mt-5">
    <div class="col-4">
      <span id="govahiname">0</span> گواهینامه
    </div>
    <div class="col-4">
      <span id="projhe">0</span> پروژه
    </div>
    <div class="col-4">
      <span id="moshtari">0</span> مشتری
    </div>
  </div>
</div>

额外优化建议

  • 如果想要更丝滑的动画,可以把setInterval换成requestAnimationFrame,不过上面的方案已经足够流畅
  • 调整animateCount的duration参数可以控制计数快慢,比如设为3000就是3秒完成计数
  • 如果页面有动态更新内容的场景,可以重置hasCounted标记,重新触发检测逻辑

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.14 09:14:04