Asp.net Core站点页面加载完成后如何触发顶部odometer数字滚动计数器效果
问题根本原因
你使用的odometer组件默认会在DOM解析完成后立即执行「可见区域检测+动画触发」逻辑,此时页面样式、资源还未加载完成,布局尚未稳定,首屏Banner区域的计数器会被误判为「已经进入可视区域」,提前跑完动画。等页面完全加载完成用户可见时,动画已经结束,自然只能看到最终数值。
可行解决方案
方案1:延迟初始化+手动触发动画(改造成本最低)
适合使用现成odometer插件的场景:
- 先修改Razor代码,把原本的
data-count改为自定义存储属性,避免插件自动读取提前触发:
<div class="funfacts-area"> <div class="row"> @foreach (var item in LandingItems) { <div class="col-lg-3 col-md-3 col-6 col-sm-3"> <div class="funfact"> <h3><span class="odometer" data-origin-count="@item.count" dir="ltr">00</span>+</h3> <p>@item.name</p> </div> </div> } </div> </div>
- 页面所有资源加载完成后,再初始化odometer并手动赋值触发动画:
// 等图片、样式等所有资源加载完成后再执行 $(window).on('load', function() { // 初始化所有odometer实例,初始值设为0 $('.odometer').each(function() { // 以下为HubSpot odometer的初始化示例,可根据你使用的插件API调整 new Odometer({ el: this, value: 0, // 其他原有配置参数保持不变 }); }); // 延迟100ms确保布局完全稳定后再赋值触发动画 setTimeout(() => { $('.odometer').each(function() { const targetCount = $(this).data('origin-count'); // odometer检测到值变化会自动触发滚动动画 $(this).text(targetCount); }); }, 100); });
方案2:用IntersectionObserver自行控制可见性触发
如果站点有大量滚动触发动画,该方案性能和兼容性更好,也能适配动态加载内容的触发需求:
$(window).on('load', function() { // 初始化交叉观察器 const observer = new IntersectionObserver((entries) => { entries.forEach(entry => { // 元素进入可视区域时触发 if (entry.isIntersecting) { const odometerEl = entry.target; const targetCount = $(odometerEl).data('origin-count'); // 初始化并触发动画 new Odometer({ el: odometerEl, value: 0 }); odometerEl.innerText = targetCount; // 触发后取消观察,避免重复执行 observer.unobserve(odometerEl); } }); }, { threshold: 0.1 // 元素露出10%即可触发 }); // 给所有odometer元素绑定观察 $('.odometer').each(function() { observer.observe(this); }); });
其他注意事项
- 如果你使用的是模板封装好的odometer组件,可以先找到模板中初始化odometer的代码,把执行时机从
$(document).ready()改为$(window).load(),即可快速解决问题。 - 不推荐使用动态渲染PartialView的方案,除非渲染完成后手动调用一次odometer的刷新检测方法,否则插件识别不到新增元素,会一直显示初始值00。
内容的提问来源于stack exchange,提问作者Mohammad Behrouzi
相关产品推荐
相关产品推荐

