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

如何在包含计数器的div滚动到视图时触发计数函数?

嘿,这个场景太常见了——用户滚动到计数器区域时,数字已经跑完了,完全没起到动态展示的效果对吧?别担心,咱们用**IntersectionObserver(交叉观察器)**就能完美解决,这是现代浏览器推荐的方案,性能比监听scroll事件好太多。下面给你一套完整的可落地代码:

实现步骤

1. 基础HTML结构

先给计数器容器加个自定义属性存储目标数值,方便后续JS读取:

<!-- 放在页面下方的计数器容器 -->
<div class="counter-container" data-target="896">0</div>

2. 简单CSS样式(可选)

给容器加个样式,让它更显眼,同时用margin把它推到页面下方方便测试:

.counter-container {
  font-size: 3.5rem;
  font-weight: 700;
  color: #2c3e50;
  margin: 1200px 0; /* 让容器处于页面下方,模拟真实场景 */
  text-align: center;
}

3. 核心JavaScript逻辑

这里分两部分:平滑计数函数 + 视口监听逻辑:

// 平滑计数函数:从0递增到目标值
function startCounter(element) {
  const targetNum = parseInt(element.dataset.target);
  let currentNum = 0;
  // 计算每一步的增量,分100步完成(数值越大,计数越慢)
  const step = targetNum / 100;
  // 定时器更新数值
  const timer = setInterval(() => {
    currentNum += step;
    // 到达目标值后停止定时器
    if (currentNum >= targetNum) {
      currentNum = targetNum;
      clearInterval(timer);
    }
    // 取整后更新文本内容
    element.textContent = Math.floor(currentNum);
  }, 18); // 每18ms更新一次,可调整计数速度
}

// 用IntersectionObserver监听容器是否进入视口
const counterBox = document.querySelector('.counter-container');
const observer = new IntersectionObserver((entries) => {
  entries.forEach(entry => {
    // 当元素进入视口时触发计数
    if (entry.isIntersecting) {
      startCounter(entry.target);
      // 只触发一次,观察完成后停止监听
      observer.unobserve(entry.target);
    }
  });
}, { 
  threshold: 0.1 // 当元素10%进入视口时触发,可调整触发时机
});

// 开始观察目标容器
observer.observe(counterBox);
关键细节说明
  • IntersectionObserver优势:相比传统的scroll事件监听,它不会在用户滚动时频繁触发回调,性能更优,浏览器原生支持(兼容Chrome、Firefox、Edge,IE不支持)
  • 触发时机调整:threshold参数可以设为0~1之间的数值,比如设为0.5就是元素一半进入视口时开始计数
  • 复用性:如果页面有多个计数器,只要给每个容器加data-target属性,然后用querySelectorAll遍历监听即可
  • 避免重复触发:调用observer.unobserve()确保计数只执行一次,不会因为用户来回滚动重复启动
兼容旧浏览器方案(比如IE)

如果需要兼容IE,可以用scroll事件结合getBoundingClientRect()判断元素是否在视口:

// 判断元素是否在视口内的工具函数
function isElementInViewport(el) {
  const rect = el.getBoundingClientRect();
  return (
    rect.top >= 0 &&
    rect.left >= 0 &&
    rect.bottom <= (window.innerHeight || document.documentElement.clientHeight) &&
    rect.right <= (window.innerWidth || document.documentElement.clientWidth)
  );
}

let isCounted = false;
const counterBox = document.querySelector('.counter-container');

window.addEventListener('scroll', () => {
  if (isElementInViewport(counterBox) && !isCounted) {
    startCounter(counterBox);
    isCounted = true;
    // 计数完成后移除scroll监听,优化性能
    window.removeEventListener('scroll', arguments.callee);
  }
});

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.22 08:29:37