countUp.js 初始化需确保库已加载且DOM就绪,应将脚本置于countUp.min.js之后、</body>前,或用DOMContentLoaded包裹;若元素已有初始值,须显式传入startVal参数。

countUp.js 怎么初始化才不会报 countUp is not defined
直接在 HTML 里写 <script>new countUp(...)</script> 却报错,大概率是脚本加载顺序错了。countUp.js 必须在 DOM 加载完成、且库已加载的前提下才能调用。
常见错误场景:把初始化代码写在 <head> 里,或放在 countUp.min.js 引入之前。
- 确保
<script src="countUp.min.js"></script>在初始化代码之前(推荐放在</body>前) - 如果依赖 DOM 元素,用
document.addEventListener('DOMContentLoaded', ...)包一层,或把初始化逻辑移到元素下方 - 使用模块方式(ESM)时,不能直接在全局作用域 new countUp;需用
import { CountUp } from 'countup.js',且注意构建工具是否处理了 .mjs 后缀
怎么让数字从 0 动画到目标值,但初始值不是 0?
countUp 默认从 0 开始,但实际页面中,你可能已经渲染了某个数值(比如服务端吐出的 <span id="sales">12847</span>),希望它从这个值“向上动”到最终值。这时不能直接传 0 作起始值。
正确做法是显式指定 startVal 参数:
立即学习“前端免费学习笔记(深入)”;
const el = document.getElementById('sales');
const numAnim = new CountUp(el, 25693, {
startVal: parseInt(el.textContent) || 0,
duration: 2.5
});
numAnim.start();
-
startVal和endVal都必须是数字类型,字符串会静默失败 - 若元素内容含单位(如
"12,847 元"),需先用正则清理:parseInt(el.innerText.replace(/[^0-9.-]/g, '')) - 不设
startVal时,countUp 内部默认用0,和元素当前文本无关
动画卡顿、跳变或没触发?检查这三处
countUp 本身轻量,但表现异常往往来自外部干扰。最常踩的坑不是 API 用错,而是环境没理清。
- CSS 设置了
opacity: 0或visibility: hidden的父容器——countUp 不会自动监听显示状态,得等元素可见后再调用.start() - 目标元素被 Vue/React 等框架管理,且初始渲染时值为空或 undefined——确保
el.textContent在实例化前已有合法数字,否则startVal取出来是NaN - 多个 countUp 实例共用同一 DOM 节点(比如重复执行初始化),旧实例未销毁,新实例覆盖失败;建议加 guard:
if (!el.__countUpInstance) { el.__countUpInstance = new CountUp(...) }
想兼容 IE11?别用新版 countUp.js
v2.0+ 的 countUp.js(即 npm 上的 countup.js)已放弃 IE 支持,用了 const、箭头函数和 requestAnimationFrame 的现代写法。IE11 直接报语法错误。
解决方案只有两个:
- 降级使用 v1.9.3(GitHub release 页面可下载
countUp-1.9.3.min.js),它基于 ES5,无依赖,IE11 可跑 - 改用更轻量的替代方案,如
odometer.js(需额外 CSS)或手写 30 行 requestAnimationFrame 循环(适合只做简单整数动画) - 如果项目已用 webpack,可通过
browserslist+@babel/preset-env尝试转译,但 v2 源码含class语法,转译后仍可能因Promise缺失而挂,不推荐
真正麻烦的不是动画本身,而是你不确定用户是否在滚动到可视区时才启动它——这时候得自己加 IntersectionObserver 判断,而老版本 countUp 并不内置这个逻辑。



















