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

如何将JavaScript计算的百分比值传入CSS动画中?

问题描述

我需要将JavaScript计算得到的百分比值c2_percent传入CSS动画show-bar-eight中,替换该动画100%关键帧里的固定30%值,让条形图能从0扩展到计算出的对应比例。

现有代码

HTML结构

<div class="bar-graph bar-graph-horizontal bar-graph-one">
  <div class="bar-one">
    <span class="rating-a1">A1</span>
    <div class="bar" id="rating-a1" data-percentage=""></div>
  </div>
  <div class="bar-two">
    <span class="rating-a2">A2</span>
    <div class="bar" data-percentage="11%"></div>
  </div>
  <div class="bar-three">
    <span class="rating-a3">A3</span>
    <div class="bar" data-percentage="7%"></div>
  </div>
  <div class="bar-four">
    <span class="rating-b1">B1</span>
    <div class="bar" data-percentage="10%"></div>
  </div>
  <div class="bar-five">
    <span class="rating-b2">B2</span>
    <div class="bar" data-percentage="20%"></div>
  </div>
  <div class="bar-six">
    <span class="rating-b3">B3</span>
    <div class="bar" data-percentage="5%"></div>
  </div>
  <div class="bar-seven">
    <span class="rating-c1">C1</span>
    <div class="bar" data-percentage="9%"></div>
  </div>
  <div class="bar-eight">
    <span class="rating-c2">C2</span>
    <div class="bar" id="c2-rating" data-percentage=""></div>
  </div>
  <div class="bar-nine">
    <span class="rating-c3">C3</span>
    <div class="bar" data-percentage="5%"></div>
  </div>
  <div class="bar-ten">
    <span class="rating-d1">D1</span>
    <div class="bar" data-percentage="5%"></div>
  </div>
</div>

CSS动画

@-webkit-keyframes show-bar-eight {
  0% {
    width: 0;
  }
  100% {
    width: 30%;
  }
}

JavaScript计算逻辑

for(let i = 0; i < 1; i++) {
  const c2_security_values = Array.from(document.querySelectorAll('.security-value-c2'));
  const c2_security_values_inner = c2_security_values.map((element) => element.innerText);
  const c2_summed_values = c2_security_values_inner.reduce((accumulator, currentValue) => parseInt(accumulator) + parseInt(currentValue));

  const total_security_values = Array.from(document.querySelectorAll('.individual-market-value'));
  const total_security_values_inner = total_security_values.map((element) => element.innerText);
  const total_summed_values = total_security_values_inner.reduce((accumulator, currentValue) => parseInt(accumulator) + parseInt(currentValue));

  const c2_percent = c2_summed_values / total_summed_values
}

解决方案

方法一:使用CSS自定义属性(推荐)

这是最灵活且易维护的方案,通过CSS变量动态传递计算值:

  1. 修改CSS动画,用变量替代固定值:
@-webkit-keyframes show-bar-eight {
  0% {
    width: 0;
  }
  100% {
    width: var(--target-width, 30%); /* 30%作为降级默认值 */
  }
}
@keyframes show-bar-eight { /* 补充标准写法兼容非webkit浏览器 */
  0% {
    width: 0;
  }
  100% {
    width: var(--target-width, 30%);
  }
}
/* 给条形图绑定动画类 */
.bar.show-bar-animation {
  -webkit-animation: show-bar-eight 1s forwards;
  animation: show-bar-eight 1s forwards;
}
  1. 修改JavaScript,计算后设置变量并触发动画:
for(let i = 0; i < 1; i++) {
  const c2_security_values = Array.from(document.querySelectorAll('.security-value-c2'));
  const c2_security_values_inner = c2_security_values.map((element) => element.innerText);
  const c2_summed_values = c2_security_values_inner.reduce((accumulator, currentValue) => parseInt(accumulator) + parseInt(currentValue));

  const total_security_values = Array.from(document.querySelectorAll('.individual-market-value'));
  const total_security_values_inner = total_security_values.map((element) => element.innerText);
  const total_summed_values = total_security_values_inner.reduce((accumulator, currentValue) => parseInt(accumulator) + parseInt(currentValue));

  const c2_percent = (c2_summed_values / total_summed_values) * 100; // 转换为百分比数值
  const c2Bar = document.getElementById('c2-rating');
  
  // 设置CSS变量
  c2Bar.style.setProperty('--target-width', `${c2_percent}%`);
  // 更新data-percentage属性
  c2Bar.setAttribute('data-percentage', `${c2_percent.toFixed(1)}%`);
  // 添加动画类触发动画
  c2Bar.classList.add('show-bar-animation');
}

方法二:动态创建CSS样式规则

如果需要兼容不支持CSS变量的旧浏览器,可以用JS动态生成动画规则:

for(let i = 0; i < 1; i++) {
  // 保留原计算逻辑
  const c2_security_values = Array.from(document.querySelectorAll('.security-value-c2'));
  const c2_security_values_inner = c2_security_values.map((element) => element.innerText);
  const c2_summed_values = c2_security_values_inner.reduce((accumulator, currentValue) => parseInt(accumulator) + parseInt(currentValue));

  const total_security_values = Array.from(document.querySelectorAll('.individual-market-value'));
  const total_security_values_inner = total_security_values.map((element) => element.innerText);
  const total_summed_values = total_security_values_inner.reduce((accumulator, currentValue) => parseInt(accumulator) + parseInt(currentValue));

  const c2_percent = (c2_summed_values / total_summed_values) * 100;
  
  // 创建动态样式
  const style = document.createElement('style');
  style.textContent = `
    @-webkit-keyframes show-bar-eight {
      0% { width: 0; }
      100% { width: ${c2_percent}%; }
    }
    @keyframes show-bar-eight {
      0% { width: 0; }
      100% { width: ${c2_percent}%; }
    }
    #c2-rating {
      -webkit-animation: show-bar-eight 1s forwards;
      animation: show-bar-eight 1s forwards;
    }
  `;
  document.head.appendChild(style);
  
  // 更新data-percentage属性
  document.getElementById('c2-rating').setAttribute('data-percentage', `${c2_percent.toFixed(1)}%`);
}

方法三:纯JavaScript控制动画

完全不用CSS关键帧,用requestAnimationFrame手动控制宽度变化:

for(let i = 0; i < 1; i++) {
  // 保留原计算逻辑
  const c2_security_values = Array.from(document.querySelectorAll('.security-value-c2'));
  const c2_security_values_inner = c2_security_values.map((element) => element.innerText);
  const c2_summed_values = c2_security_values_inner.reduce((accumulator, currentValue) => parseInt(accumulator) + parseInt(currentValue));

  const total_security_values = Array.from(document.querySelectorAll('.individual-market-value'));
  const total_security_values_inner = total_security_values.map((element) => element.innerText);
  const total_summed_values = total_security_values_inner.reduce((accumulator, currentValue) => parseInt(accumulator) + parseInt(currentValue));

  const c2_percent = (c2_summed_values / total_summed_values) * 100;
  const c2Bar = document.getElementById('c2-rating');
  const targetWidth = c2_percent;
  const duration = 1000; // 动画时长1秒
  let startTime;

  function animate(timestamp) {
    if (!startTime) startTime = timestamp;
    const elapsed = timestamp - startTime;
    const progress = Math.min(elapsed / duration, 1);
    c2Bar.style.width = `${progress * targetWidth}%`;
    
    if (progress < 1) {
      requestAnimationFrame(animate);
    } else {
      c2Bar.setAttribute('data-percentage', `${targetWidth.toFixed(1)}%`);
    }
  }

  requestAnimationFrame(animate);
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.23 01:03:11