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

如何用JavaScript/React实现动画?点击后定时修改opacity不生效问题

代码存在的核心问题

  • 你使用的setTimeout是单次执行定时器,仅会在触发后100毫秒执行1次回调逻辑,不会循环执行。所以每次调用change函数都只会运行一次o = 0 + 0.1的计算,输出自然始终为0.1。
  • 变量o的作用域被限制在change函数内部,每次调用change都会重新将o初始化为0,即便替换为循环定时器,只要o的声明位置不变,每次执行都会从0开始累加。

补充注意:0.1属于十进制不精确浮点数,连续累加可能会出现0.30000000000000004这类精度问题,必要时可以用o = Number((o + 0.1).toFixed(1))做精度处理。

修复方案

方案1:使用setInterval实现循环执行

将状态变量提到函数外部,用循环定时器定期修改属性,适合对间隔精度要求不高的场景:

// 将状态变量和定时器标识提到全局作用域,避免每次调用change被重置
var opacity = 0;
var timer = null;
function change () {
  // 每次调用先清理之前的定时器,避免重复触发多个定时器
  if(timer) clearInterval(timer);
  timer = setInterval(function() {
    opacity += 0.1;
    // opacity合法范围是0-1,达到最大值后停止定时器
    if(opacity >= 1) {
      opacity = 1;
      clearInterval(timer);
    }
    document.querySelector("div.label").style.opacity = opacity;
    console.log("o = " + opacity);
  }, 100)
}

方案2:递归调用setTimeout实现(间隔精度更高)

如果需要避免setInterval因为回调执行阻塞导致的间隔累积误差,可以用递归调用setTimeout的方式实现,状态变量通过闭包保存:

function change () {
  var opacity = 0;
  function step() {
    opacity += 0.1;
    if(opacity >= 1) {
      opacity = 1;
      document.querySelector("div.label").style.opacity = opacity;
      console.log("o = " + opacity);
      return;
    }
    document.querySelector("div.label").style.opacity = opacity;
    console.log("o = " + opacity);
    setTimeout(step, 100);
  }
  step();
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.27 15:15:03