You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Django模板中JS滚动计数动画失效问题排查求助

滚动触发计数动画失效的修复

问题代码

HTML(Django模板)

<section class="numc">
    <div class="nums">
        <div class="num" data-goal="50">0</div>
        <div class="num" data-goal="60">0</div>
        <div class="num" data-goal="100">0</div>
    </div>
</section>
<script src="{% static 'javascript/js.js' %}"></script>

原JS代码

let nums = document.querySelectorAll(".nums .num");
let section = document.querySelector(".numc");


window.onscroll = function () {
    if (window.scrollY >= section.offsetTop) {
      nums.forEach((num) => startCount(num));
    }
};

function startCount(el) {
    let goal = el.dataset.goal;
    let count = setInterval(() => {
        el.textcontent++;
        if (el.textcontent == goal) {
            clearInterval(count);
        }
    }, 10);
}

错误分析与修复要点

  • 属性名拼写错误:textcontent应为DOM标准驼峰属性名textContent,拼写错误会导致无法修改元素文本。
  • 滚动重复触发:滚动事件会持续触发,多次调用startCount会导致多个计数器同时运行,数字跳变。需添加标记确保计数仅执行一次。
  • 类型不匹配:dataset.goal返回字符串,直接与数字比较会引发逻辑错误,需转为数字类型。
  • 视口判断不准确:仅用scrollY >= section.offsetTop会在元素顶部刚触达页面顶部就触发,应判断元素是否进入视口(至少部分可见)。

修正后的JS代码

let nums = document.querySelectorAll(".nums .num");
let section = document.querySelector(".numc");
let hasTriggered = false; // 标记计数是否已触发

// 判断元素是否进入视口
function isElementInViewport(el) {
    const rect = el.getBoundingClientRect();
    return rect.top <= window.innerHeight && rect.bottom >= 0;
}

window.onscroll = function () {
    if (isElementInViewport(section) && !hasTriggered) {
        hasTriggered = true;
        nums.forEach((num) => startCount(num));
    }
};

function startCount(el) {
    let current = 0;
    const goal = parseInt(el.dataset.goal, 10); // 转为整数类型
    const increment = Math.ceil(goal / 100); // 统一计数步长,让动画更协调
    const count = setInterval(() => {
        current += increment;
        // 到达目标值时停止计数
        if (current >= goal) {
            current = goal;
            clearInterval(count);
        }
        el.textContent = current; // 修正属性名
    }, 20); // 调整间隔,优化动画流畅度
}

额外优化说明

  • 新增hasTriggered变量,避免滚动时重复触发计数逻辑。
  • 使用getBoundingClientRect()实现更精准的视口判断,适配不同屏幕尺寸。
  • 通过计算increment步长,让不同目标值的计数速度保持一致,提升视觉体验。

内容的提问来源于stack exchange,提问作者Taha Alsaity

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.20 03:13:17