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

如何实现滚动到对应区块时触发进度条动画显示的功能

滚动触发视口动画解决方案

你的原有代码会在页面加载完成后立即执行所有进度条的动画,只需修改JS逻辑,通过元素可视区域检测实现滚动触发即可,原有HTML、CSS代码无需调整。

优先方案:IntersectionObserver 实现(性能最优)

该API是浏览器原生提供的元素交叉检测接口,无需频繁计算滚动偏移,性能远好于传统scroll监听方案:

$(function() {
  const animatedClass = 'skill_animated';
  // 初始化交叉观察器
  const observer = new IntersectionObserver((entries) => {
    entries.forEach(item => {
      // 元素进入视口且未执行过动画时触发
      if (item.isIntersecting && !$(item.target).hasClass(animatedClass)) {
        const $perBar = $(item.target);
        const targetWidth = $perBar.attr('per');
        $perBar.addClass(animatedClass)
               .css('width', targetWidth + '%');
        $perBar.find('.value').text(targetWidth + '%').css('opacity', '1');
      }
    })
  }, {
    threshold: 0.15 // 可自定义触发阈值:0-1之间,代表元素露出视口的比例
  })

  // 给所有进度条绑定观察
  $(".skill_per").each(function() {
    observer.observe(this);
  })
});

兼容方案:scroll监听实现(兼容旧浏览器)

如果需要适配不支持IntersectionObserver的旧浏览器,可使用scroll事件+节流实现,注意添加节流逻辑避免性能损耗:

$(function() {
  const animatedClass = 'skill_animated';
  const $perBars = $(".skill_per");

  // 节流函数:控制滚动事件触发频率
  function throttle(fn, delay) {
    let timer = null;
    return function() {
      if (timer) return;
      timer = setTimeout(() => {
        fn.apply(this, arguments);
        timer = null;
      }, delay)
    }
  }

  // 检测元素是否进入视口
  function isInViewport(el) {
    const rect = el.getBoundingClientRect();
    return (
      rect.top >= 0 &&
      rect.left >= 0 &&
      rect.bottom <= (window.innerHeight || document.documentElement.clientHeight) &&
      rect.right <= (window.innerWidth || document.documentElement.clientWidth)
    )
  }

  // 检查所有未触发动画的进度条
  function checkAnimate() {
    $perBars.not(`.${animatedClass}`).each(function() {
      if (isInViewport(this)) {
        const $perBar = $(this);
        const targetWidth = $perBar.attr('per');
        $perBar.addClass(animatedClass)
               .css('width', targetWidth + '%');
        $perBar.find('.value').text(targetWidth + '%').css('opacity', '1');
      }
    })
  }

  // 页面加载先执行一次,避免元素初始就在视口时不触发动画
  checkAnimate();
  // 滚动时绑定节流后的检测逻辑,100ms检测一次可自行调整
  $(window).on('scroll', throttle(checkAnimate, 100));
});

两种方案都添加了动画已执行的标记类,避免元素反复进出视口时重复触发动画,不需要重复触发的话无需修改,需要重复触发移除addClass相关逻辑即可。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.11 09:54:02