
通过监听页面滚动,当目标区域进入视口时触发数字从0开始平滑递增至设定值的动画效果,适用于统计指标展示,纯html/css/js即可实现,无需框架。
通过监听页面滚动,当目标区域进入视口时触发数字从0开始平滑递增至设定值的动画效果,适用于统计指标展示,纯html/css/js即可实现,无需框架。
实现“滚动触发动画数字计数器”是一种常见且高效的视觉增强技巧,广泛用于企业官网、作品集或数据看板中(如您提到的 hospice 主题示例)。其核心逻辑是:仅在用户滚动至目标区域(如统计模块)时启动数字动画,停止滚动后动画自然完成,不持续运行,兼顾性能与体验。
以下是一个轻量、兼容性好、无外部依赖(仅需 jQuery)的完整实现方案:
✅ 基础结构(HTML)
为每个待动画的数字添加 class="counter",并用 id="counter" 标识整个统计区块,便于滚动定位:
<section id="counter" class="statistics"><div class="stastic">
<h4 class="counter">500</h4>
<p>Projects Done</p>
</div>
<div class="stastic">
<h4 class="counter">10</h4>
<p>Years Experience</p>
</div>
<div class="stastic">
<h4 class="counter">100</h4>
<p>Success Rate</p>
</div>
</section>
? 注意:数字文本即为目标值(如 500),动画将从 0 动态增长至此值。
Codex Bridge下载一款AI工具,主要用于将编码任务调度到本地 OpenAI Codex CLI,支持后台执行、状态轮询以及可交互式回答的澄清问题。适用于 OpenClaw 需要……,适合需要提升相关任务效率的用户。
? 样式布局(CSS)
使用现代 CSS Grid 实现响应式三列布局,并确保文字居中、背景清晰:
.statistics {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(280px, 1fr));
gap: 20px;
padding: 2rem 1rem;
}
.stastic {
text-align: center;
background-color: #ffefdb;
border-radius: 8px;
padding: 1.5rem;
box-shadow: 0 2px 6px rgba(0,0,0,0.05);
}
.stastic h4 {
font-size: 2.5rem;
font-weight: 700;
margin: 0 0 0.5rem 0;
color: #2c3e50;
}
.stastic p {
margin: 0;
color: #7f8c8d;
font-size: 1rem;
}
⚙️ 交互逻辑(JavaScript + jQuery)
关键点在于防重复触发和精准触发时机:
- 使用 a == 0 标志位确保动画只执行一次;
- 计算 #counter 元素顶部距离视口底部(offset().top - window.innerHeight),当滚动超过该位置即视为进入可视区;
- 利用 jQuery .animate() 驱动数字变化,step 回调实时更新 DOM,Math.ceil() 确保整数显示;
- 动画时长设为 2000ms,缓动函数 swing 提供自然加速度。
let hasAnimated = false;
$(window).on('scroll', function () {
const $counterSection = $('#counter');
const sectionTop = $counterSection.offset().top;
const windowHeight = $(window).height();
const scrollPos = $(this).scrollTop();
// 当区块进入视口底部(即用户已看到该区域)且未动画过
if (!hasAnimated && scrollPos + windowHeight >= sectionTop) {
$('.counter').each(function () {
const $el = $(this);
const targetValue = parseInt($el.text(), 10) || 0;
$({ count: 0 }).animate(
{ count: targetValue },
{
duration: 2000,
easing: 'swing',
step: (now) => $el.text(Math.floor(now)),
complete: () => $el.text(targetValue) // 确保最终值精确
}
);
});
hasAnimated = true; // 锁定,避免重复触发
}
});
? 进阶建议与注意事项
-
原生替代方案:若希望摆脱 jQuery,可使用 IntersectionObserver API 实现更高效、更现代的进入视口检测(兼容性 ≥ Chrome 63 / Edge 79 / Safari 12.1):
const observer = new IntersectionObserver((entries) => { entries.forEach(entry => { if (entry.isIntersecting && !entry.target.hasAttribute('data-animated')) { animateCounters(entry.target); entry.target.setAttribute('data-animated', 'true'); } }); }, { threshold: 0.1 }); observer.observe(document.getElementById('counter')); 框架选型说明:React/Vue 等框架在复杂状态管理或多组件联动场景下更具优势,但对单个滚动数字动画而言,原生方案更轻量、加载更快、调试更直观,无需额外构建流程或学习成本。
性能提示:避免在 scroll 事件中直接执行重绘操作;本例已通过节流(标志位)优化,实际项目中可进一步结合 requestAnimationFrame 或 debounce 提升流畅度。
只要将上述 HTML、CSS、JS 组合,即可快速集成一个专业级滚动数字动画模块——简洁、可靠、开箱即用。











