0

0

如何让数字计数器在滚动到指定区域时才开始动画

心靈之曲

心靈之曲

发布时间:2026-02-02 19:50:02

|

707人浏览过

|

来源于php中文网

原创

如何让数字计数器在滚动到指定区域时才开始动画

本文介绍如何通过监听页面滚动事件,精准触发数字计数动画——仅当目标统计区块进入视口时启动 `animate()` 函数,避免页面加载即执行导致的“已计完”问题,并提供防重复触发、性能优化及现代替代方案。

实现“滚动到才开始计数”的核心思路是:不依赖 window.onload 全局加载完成就执行动画,而是动态监听用户滚动行为,实时判断目标容器是否进入可视区域(viewport),满足条件后首次触发计数动画。

✅ 正确做法:基于 getBoundingClientRect() 的滚动检测

首先,修正 HTML 中非法 ID 命名(ID 不应以纯数字开头,如 '0101' 违反规范):


0

0

0

JavaScript 部分改写为现代、健壮的实现(移除内联 onscroll,使用 addEventListener 并节流):

// 获取 DOM 元素(使用合法 ID)
const text1 = document.getElementById('counter-visits');
const text2 = document.getElementById('counter-members');
const text3 = document.getElementById('counter-satisfaction');

// 目标容器(计数器所在区块)
const container = document.querySelector('.container');

// 动画函数(保持原逻辑,已优化 requestAnimationFrame)
function animate(obj, initVal, lastVal, duration) {
  let startTime = null;
  const step = (currentTime) => {
    if (!startTime) startTime = currentTime;
    const progress = Math.min((currentTime - startTime) / duration, 1);
    obj.textContent = Math.floor(progress * (lastVal - initVal) + initVal);
    if (progress < 1) requestAnimationFrame(step);
  };
  requestAnimationFrame(step);
}

// 控制变量:确保只触发一次
let animationStarted = false;

// 滚动检测函数
function checkScrollPosition() {
  if (animationStarted) return;

  const rect = container.getBoundingClientRect();
  // 当容器顶部进入视口(即 rect.top <= window.innerHeight)
  if (rect.top <= window.innerHeight && rect.bottom >= 0) {
    animate(text1, 0, 100, 3000);
    animate(text2, 0, 300, 3000);
    animate(text3, 0, 100, 3000);
    animationStarted = true;
  }
}

// 添加带节流的滚动监听(防高频触发)
let ticking = false;
window.addEventListener('scroll', () => {
  if (!ticking) {
    requestAnimationFrame(() => {
      checkScrollPosition();
      ticking = false;
    });
    ticking = true;
  }
});

// 页面加载后立即检查一次(兼容初始已在目标位置的情况)
checkScrollPosition();

⚠️ 注意事项与最佳实践

  • ID 合法性:HTML ID 必须以字母开头,id="0101" 是无效的,会导致 getElementById 在部分环境失败或行为不可预测,务必改为 id="counter-visits" 等语义化命名。

  • 性能优化:直接监听 scroll 事件极易造成卡顿。本方案采用 requestAnimationFrame 节流,确保每帧最多执行一次检测。

    Midjourney
    Midjourney

    当前最火的AI绘图生成工具,可以根据文本提示生成华丽的视觉图片。

    下载
  • 视口判定更精准:使用 getBoundingClientRect().top = 0 判断元素是否部分进入视口(比单纯比较 scrollY 更可靠,兼容缩放、响应式布局)。

  • 现代替代方案(推荐进阶使用):可改用 Intersection Observer API,代码更简洁、性能更优:

    const observer = new IntersectionObserver((entries) => {
      if (entries[0].isIntersecting && !animationStarted) {
        animate(text1, 0, 100, 3000);
        animate(text2, 0, 300, 3000);
        animate(text3, 0, 100, 3000);
        animationStarted = true;
        observer.unobserve(container); // 观察一次后停止
      }
    }, { threshold: 0.1 }); // 当 10% 可见时触发
    
    observer.observe(container);

✅ 总结

让计数器“懒启动”的关键在于解耦动画触发时机与页面加载时机。通过滚动监听 + 视口检测 + 单次触发控制,即可优雅实现“所见即所动”。优先采用 IntersectionObserver(支持主流浏览器),若需兼容旧版 IE,则使用节流后的 scroll + getBoundingClientRect 方案。同时务必修正 HTML ID 规范,保障脚本长期稳定运行。

热门AI工具

更多
DeepSeek
DeepSeek

幻方量化公司旗下的开源大模型平台

豆包大模型
豆包大模型

字节跳动自主研发的一系列大型语言模型

通义千问
通义千问

阿里巴巴推出的全能AI助手

腾讯元宝
腾讯元宝

腾讯混元平台推出的AI助手

文心一言
文心一言

文心一言是百度开发的AI聊天机器人,通过对话可以生成各种形式的内容。

讯飞写作
讯飞写作

基于讯飞星火大模型的AI写作工具,可以快速生成新闻稿件、品宣文案、工作总结、心得体会等各种文文稿

即梦AI
即梦AI

一站式AI创作平台,免费AI图片和视频生成。

ChatGPT
ChatGPT

最最强大的AI聊天机器人程序,ChatGPT不单是聊天机器人,还能进行撰写邮件、视频脚本、文案、翻译、代码等任务。

相关专题

更多
PHP 高并发与性能优化
PHP 高并发与性能优化

本专题聚焦 PHP 在高并发场景下的性能优化与系统调优,内容涵盖 Nginx 与 PHP-FPM 优化、Opcode 缓存、Redis/Memcached 应用、异步任务队列、数据库优化、代码性能分析与瓶颈排查。通过实战案例(如高并发接口优化、缓存系统设计、秒杀活动实现),帮助学习者掌握 构建高性能PHP后端系统的核心能力。

102

2025.10.16

PHP 数据库操作与性能优化
PHP 数据库操作与性能优化

本专题聚焦于PHP在数据库开发中的核心应用,详细讲解PDO与MySQLi的使用方法、预处理语句、事务控制与安全防注入策略。同时深入分析SQL查询优化、索引设计、慢查询排查等性能提升手段。通过实战案例帮助开发者构建高效、安全、可扩展的PHP数据库应用系统。

90

2025.11.13

JavaScript 性能优化与前端调优
JavaScript 性能优化与前端调优

本专题系统讲解 JavaScript 性能优化的核心技术,涵盖页面加载优化、异步编程、内存管理、事件代理、代码分割、懒加载、浏览器缓存机制等。通过多个实际项目示例,帮助开发者掌握 如何通过前端调优提升网站性能,减少加载时间,提高用户体验与页面响应速度。

30

2025.12.30

AO3官网入口与中文阅读设置 AO3网页版使用与访问
AO3官网入口与中文阅读设置 AO3网页版使用与访问

本专题围绕 Archive of Our Own(AO3)官网入口展开,系统整理 AO3 最新可用官网地址、网页版访问方式、正确打开链接的方法,并详细讲解 AO3 中文界面设置、阅读语言切换及基础使用流程,帮助用户稳定访问 AO3 官网,高效完成中文阅读与作品浏览。

19

2026.02.02

主流快递单号查询入口 实时物流进度一站式追踪专题
主流快递单号查询入口 实时物流进度一站式追踪专题

本专题聚合极兔快递、京东快递、中通快递、圆通快递、韵达快递等主流物流平台的单号查询与运单追踪内容,重点解决单号查询、手机号查物流、官网入口直达、包裹进度实时追踪等高频问题,帮助用户快速获取最新物流状态,提升查件效率与使用体验。

6

2026.02.02

Golang WebAssembly(WASM)开发入门
Golang WebAssembly(WASM)开发入门

本专题系统讲解 Golang 在 WebAssembly(WASM)开发中的实践方法,涵盖 WASM 基础原理、Go 编译到 WASM 的流程、与 JavaScript 的交互方式、性能与体积优化,以及典型应用场景(如前端计算、跨平台模块)。帮助开发者掌握 Go 在新一代 Web 技术栈中的应用能力。

1

2026.02.02

PHP Swoole 高性能服务开发
PHP Swoole 高性能服务开发

本专题聚焦 PHP Swoole 扩展在高性能服务端开发中的应用,系统讲解协程模型、异步IO、TCP/HTTP/WebSocket服务器、进程与任务管理、常驻内存架构设计。通过实战案例,帮助开发者掌握 使用 PHP 构建高并发、低延迟服务端应用的工程化能力。

2

2026.02.02

Java JNI 与本地代码交互实战
Java JNI 与本地代码交互实战

本专题系统讲解 Java 通过 JNI 调用 C/C++ 本地代码的核心机制,涵盖 JNI 基本原理、数据类型映射、内存管理、异常处理、性能优化策略以及典型应用场景(如高性能计算、底层库封装)。通过实战示例,帮助开发者掌握 Java 与本地代码混合开发的完整流程。

1

2026.02.02

go语言 注释编码
go语言 注释编码

本专题整合了go语言注释、注释规范等等内容,阅读专题下面的文章了解更多详细内容。

61

2026.01.31

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
React 教程
React 教程

共58课时 | 4.5万人学习

TypeScript 教程
TypeScript 教程

共19课时 | 2.6万人学习

Bootstrap 5教程
Bootstrap 5教程

共46课时 | 3.2万人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号