实现Odometer数字鼠标悬停时重复滚动效果的方法
实现Odometer.js鼠标悬停重复触发数字滚动动画
问题分析
原代码仅在页面加载时初始化并触发一次数字滚动动画,且未保留Odometer实例引用,导致无法后续重复调用动画逻辑。要实现鼠标悬停时单独重复触发,需要:
- 保存每个Odometer实例的引用
- 为每个统计项绑定鼠标悬停事件,触发时重置并重新播放动画
修改后的代码
JavaScript 代码
(function($) { $(document).ready(function() { // 保存所有Odometer实例,键为元素,值为实例 const odometerInstances = new Map(); const odometerElements = document.querySelectorAll('.odometer'); // 初始化所有Odometer实例 odometerElements.forEach((element) => { const targetValue = element.getAttribute('data-value'); const odometer = new Odometer({ el: element, value: 0, format: '(,ddd)', duration: 1800, // 缩短时长适配重复触发场景,可按需调整 }); odometerInstances.set(element, odometer); }); // 滚动触发初始动画(保留原需求的滚动触发逻辑) const observer = new IntersectionObserver((entries) => { entries.forEach(entry => { if (entry.isIntersecting) { const odometer = odometerInstances.get(entry.target); const targetValue = entry.target.getAttribute('data-value'); odometer.update(targetValue); // 可选:若只需触发一次滚动动画,取消注释下面一行 // observer.unobserve(entry.target); } }); }, { threshold: 0.5 }); odometerElements.forEach(el => observer.observe(el)); // 鼠标悬停触发重复动画 $('.stat-item').on('mouseenter', function() { const odometerEl = $(this).find('.odometer')[0]; const odometer = odometerInstances.get(odometerEl); const targetValue = odometerEl.getAttribute('data-value'); // 先重置为0,再更新到目标值,完整播放滚动动画 odometer.update(0); setTimeout(() => { odometer.update(targetValue); }, 100); // 短延迟确保重置生效 }); }); })(jQuery);
HTML 代码(补充缺失的Odometer资源)
<!-- 引入Odometer样式(原代码缺失,需补充) --> <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/odometer.js/0.4.8/themes/odometer-theme-default.min.css"> <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.7.1/jquery.min.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/odometer.js/0.4.8/odometer.min.js"></script> <section class="company-statistics"> <div class="container"> <div class="stats-wrapper"> <div class="stats-content row"> <div class="col-6 col-md-4 col-lg-4 stat-item"> <div class="odometer" data-value="13">0</div> </div> <div class="col-6 col-md-4 col-lg-4 stat-item"> <div class="odometer" data-value="10">0</div> </div> <div class="col-6 col-md-4 col-lg-4 stat-item"> <div class="odometer" data-value="75">0</div> </div> <div class="col-6 col-md-4 col-lg-4 stat-item"> <div class="odometer" data-value="18">0</div> </div> <div class="col-6 col-md-4 col-lg-4 stat-item"> <div class="odometer" data-value="22">0</div> </div> <div class="col-6 col-md-4 col-lg-4 d-xl-none stat-item"> <div class="odometer" data-value="45">0</div> </div> </div> </div> </div> </section>
关键说明
- 实例保存:用
Map存储每个元素对应的Odometer实例,方便后续快速获取并调用update方法 - 滚动触发优化:使用
IntersectionObserver替代原有的setTimeout,更精准地在元素进入视口时触发初始动画 - 悬停动画逻辑:鼠标悬停时先将数值重置为0,短暂延迟后更新到目标值,确保动画完整播放
- 时长调整:将原
duration从18000(18秒)改为1800(1.8秒),更适合重复触发的交互场景,可根据需求自行调整
内容的提问来源于stack exchange,提问作者Prashant Jani
相关产品推荐
相关产品推荐

