数字滚动统计组件通过自定义元素实现,基于requestAnimationFrame平滑动画,支持属性配置、懒加载、精度控制与样式隔离。

用自定义元素(Custom Element)实现数字滚动增长的统计组件,核心是封装一个可复用、声明式使用的 HTML 元素,内部用 requestAnimationFrame 驱动平滑动画,并支持起始值、目标值、持续时间、小数位、千分位等配置。
定义基础自定义元素结构
继承 HTMLElement,使用 customElements.define() 注册。组件通过 HTML 属性接收参数,例如:
-
data-end:目标数字(必填) -
data-start:起始数字(默认 0) -
data-duration:动画时长(毫秒,默认 2000) -
data-decimals:小数位数(默认 0) -
data-separator:千分位分隔符(默认 ",")
示例用法:<number-counter data-end="12345.67" data-decimals="2"></number-counter>
内部动画逻辑用 requestAnimationFrame 实现
避免 setInterval 的帧率不稳定和丢帧问题。关键步骤包括:
- 在
connectedCallback中启动动画(确保元素已挂载) - 记录动画开始时间
performance.now() - 每帧按线性比例计算当前值:
current = start + (end - start) * (elapsed / duration) - 用
Math.floor(value * scale) / scale控制小数精度(如scale = 10 ** decimals) - 格式化为带千分位的字符串:
current.toFixed(decimals).replace(/\B(?=(\d{3})+(?!\d))/g, separator) - 动画结束时清除帧请求,防止内存泄漏
支持可见区域触发(懒加载)
避免页面一打开就全部滚动,提升性能。推荐用 IntersectionObserver:
- 在
connectedCallback中创建 observer,监听元素是否进入视口 - 首次进入视口时调用动画函数,然后
unobserve防止重复触发 - 兼容性考虑可降级为 scroll 监听 + 节流,但 IntersectionObserver 更轻量、更准确
增强实用性与可维护性
让组件更健壮、易调试:
- 属性变更监听:
static get observedAttributes()返回属性数组,响应attributeChangedCallback更新目标值并重播动画 - 支持非数字输入容错:对
data-end做parseFloat()处理,无效值回退到 0 - 提供方法接口,如
start()、reset()、update(newEnd),方便 JS 主动控制 - 样式隔离:用
shadowRoot封装,内置默认字体、行高、过渡,避免全局污染


















