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

jQuery滚动触发所有类动画问题:仅触达对应进度条时执行动画

解决滚动时仅触发当前可见进度条动画的问题

你的问题核心在于只要页面滚动就会触发所有.skills元素内的进度条动画,完全没有判断每个进度条容器是否已经进入可视区域。下面是针对性的修复方案,核心思路是先检测元素是否在视口内,再按需执行动画,同时避免重复触发:

步骤1:添加「元素是否在视口内」的检测函数

这个工具函数会帮我们判断目标元素是否进入了浏览器的可视范围:

function isElementInViewport(el) {
    const rect = el.getBoundingClientRect();
    return (
        rect.top <= (window.innerHeight || document.documentElement.clientHeight) &&
        rect.bottom >= 0
    );
}

步骤2:修改滚动事件逻辑,实现按需触发动画

我们会给已经执行过动画的.skills元素添加一个标记类(比如skill-animated),防止滚动来回时重复触发动画:

// 绑定滚动事件
$(window).scroll(function() {
    checkSkillsAnimation();
});

// 页面加载时先检查一次,避免元素一开始就在视口内却不触发动画
$(document).ready(function() {
    checkSkillsAnimation();
});

function checkSkillsAnimation() {
    jQuery('.skills').each(function() {
        const $skillContainer = jQuery(this);
        // 只有元素在视口内,且未执行过动画时才触发
        if (isElementInViewport(this) && !$skillContainer.hasClass('skill-animated')) {
            $skillContainer.addClass('skill-animated');
            $skillContainer.find('.skillbar').animate({
                width: $skillContainer.attr('data-percent')
            }, 5000);
        }
    });
}

原代码问题分析

你原来的代码中,只要页面滚动就会调用startAnimation函数,而这个函数直接遍历所有.skills元素执行动画,完全没有判断元素是否可见,所以所有进度条会同时触发动画,这就是问题的根源。

额外优化建议

  • 初始化时可以给.skillbar加CSS:width: 0;,让进度条在动画前保持隐藏状态;
  • 可以给动画添加缓动效果,比如easeInOutQuad,让动画过渡更自然;
  • 为了性能优化,给滚动事件加防抖处理,避免滚动时频繁触发函数:
function debounce(func, wait) {
    let timeout;
    return function() {
        const context = this, args = arguments;
        clearTimeout(timeout);
        timeout = setTimeout(() => func.apply(context, args), wait);
    };
}

// 替换原来的滚动事件绑定
$(window).scroll(debounce(checkSkillsAnimation, 100));

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.20 10:33:36