实现滚动到指定Div时启动JS数字计数效果求助
实现滚动到目标元素时启动数字滚动计数效果
首先得指出你原来代码里的几个关键问题:
setInterval的时间参数是毫秒,你写的0.00001相当于0,浏览器会疯狂执行回调,直接导致页面卡顿,得改成合理的数值(比如16ms,接近浏览器的帧刷新间隔)- 没有做「元素是否进入视口」的判断,也没标记计数是否已执行,所以页面一加载计数就自动跑起来了
下面是完整的修复方案,一步步来:
1. 封装可复用的计数函数
先写一个通用的计数函数,支持自定义目标数值、元素ID,还能控制计数的平滑度:
// 计数函数:参数分别是元素ID、目标数值、可选的总持续时间(默认2000ms) function animateCount(elementId, target, duration = 2000) { const element = document.getElementById(elementId); if (!element) return; let current = 0; // 计算每一步的增量,基于浏览器帧间隔(约16ms)保证平滑 const step = target / (duration / 16); const timer = setInterval(() => { current += step; // 最后一步直接设为目标值,避免小数或超出 if (current >= target) { current = target; clearInterval(timer); } // 取整显示,保证数字是整数 element.textContent = Math.floor(current); }, 16); }
2. 检测元素是否进入视口
写一个工具函数,判断目标div是否滚动到了用户可见的区域:
function isElementInViewport(el) { const rect = el.getBoundingClientRect(); return ( rect.top <= window.innerHeight && rect.bottom >= 0 ); }
3. 滚动监听与触发逻辑
添加滚动事件监听,只有当目标div进入视口且计数未执行过时,才启动所有计数:
// 标记计数是否已执行,避免滚动时重复触发 let hasCounted = false; const targetDiv = document.getElementById('sumtxt'); function handleScroll() { if (!hasCounted && isElementInViewport(targetDiv)) { // 启动各个数值的计数动画 animateCount('sabeghe', 30); animateCount('moshtari', 3200); animateCount('projhe', 4600); animateCount('govahiname', 29); // 标记为已执行 hasCounted = true; // 可选:计数启动后移除滚动监听,减少性能消耗 window.removeEventListener('scroll', handleScroll); } } // 添加滚动监听 window.addEventListener('scroll', handleScroll); // 页面加载时先检查一次(如果元素一开始就在视口内,直接触发) handleScroll();
4. 修改后的HTML
去掉原来的onmouseover属性(如果不需要鼠标悬停触发的话),初始数值设为0更符合需求:
<div class="container text-center d-inline" id="sumtxt"> <strong>بیش از <span id="sabeghe">0</span> سال سابقه</strong> <div class="pt-3 pb-3 mt-5"> <div class="col-4"> <span id="govahiname">0</span> گواهینامه </div> <div class="col-4"> <span id="projhe">0</span> پروژه </div> <div class="col-4"> <span id="moshtari">0</span> مشتری </div> </div> </div>
额外优化建议
- 如果想要更丝滑的动画,可以把
setInterval换成requestAnimationFrame,不过上面的方案已经足够流畅 - 调整
animateCount的duration参数可以控制计数快慢,比如设为3000就是3秒完成计数 - 如果页面有动态更新内容的场景,可以重置
hasCounted标记,重新触发检测逻辑
内容的提问来源于stack exchange,提问作者amir zahedi
相关产品推荐
相关产品推荐

