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

Safari及移动端动画计数器失效求助(Chrome桌面端正常)

问题与解决方案

问题说明

现有一段实现0到100数字计数动画的代码,在桌面端Chrome浏览器中可正常运行过渡动画,但在Safari浏览器及移动端设备中,计数器会直接从0跳至100,无动画效果。尝试通过JS/jQuery修复后,计数器虽能运行,但出现无法按预期重置的问题。

原代码如下:

<html>
<head>
<style>
@property --num {
  syntax: "<integer>";
  initial-value: 0;
  inherits: false;
}

.div__counter--animate,
.div__counter--secondary {font: 700 6vw system-ui;}

.div__counter {
animation: counter 2.5s forwards linear ease-in-out;
-webkit-animation: counter 2.5s forwards alternate ease-in-out;
-moz-animation: counter 2.5s forwards alternate ease-in-out;
-ms-animation: counter 2.5s forwards alternate ease-in-out;
-o-animation: counter 2.5s forwards alternate ease-in-out;
  counter-reset: num var(--num);}

.div__counter::after {
content: counter(num);
animation: counter 2.5s forwards alternate ease-in-out;
-webkit-animation: counter 2.5s forwards alternate ease-in-out;
-moz-animation: counter 2.5s forwards alternate ease-in-out;
-ms-animation: counter 2.5s forwards alternate ease-in-out;
-o-animation: counter 2.5s forwards alternate ease-in-out;
  counter-reset: num var(--num);}

@-webkit-keyframes counter {
  from {
    --num: 0;
  }
  to {
    --num: 100;
  }
}

@keyframes counter {
  from {
    --num: 0;
  }
  to {
    --num: 100;
  }
}

.div__counter {font: 700 12vw system-ui !important;}
</style>
</head>
<body>
<div class="div__counter"></div>
</body>
</html>

问题原因

原代码依赖CSS自定义属性@property结合计数器实现动画,但Safari对整数类型自定义属性的动画支持存在兼容性问题,导致无法正常过渡。而后续JS修复未处理好重置逻辑,引发新问题。

解决方案

采用纯JS实现计数动画,同时支持重置功能,兼容性覆盖所有主流浏览器,包括Safari和移动端:

<html>
<head>
<style>
.div__counter {
  font: 700 12vw system-ui;
}
</style>
</head>
<body>
<div class="div__counter"></div>
<button onclick="resetCounter()">重置计数器</button>

<script>
let counterInterval;

function startCounter() {
  const counterEl = document.querySelector('.div__counter');
  let currentNum = 0;
  const targetNum = 100;
  const duration = 2500; // 动画时长2.5秒
  const step = targetNum / (duration / 16); // 按60fps计算步长

  // 先清除已有定时器,避免重复触发
  if (counterInterval) clearInterval(counterInterval);

  counterInterval = setInterval(() => {
    currentNum += step;
    if (currentNum >= targetNum) {
      currentNum = targetNum;
      clearInterval(counterInterval);
    }
    counterEl.textContent = Math.floor(currentNum);
  }, 16);
}

function resetCounter() {
  const counterEl = document.querySelector('.div__counter');
  if (counterInterval) clearInterval(counterInterval);
  counterEl.textContent = 0;
  // 可选:重置后立即重新开始动画
  // setTimeout(startCounter, 500);
}

// 页面加载完成后启动计数器
window.addEventListener('load', startCounter);
</script>
</body>
</html>

方案优势

  • 兼容性强:不依赖CSS自定义属性的高级特性,所有主流浏览器均支持
  • 可控制:支持手动重置,且重置逻辑清晰,不会出现异常
  • 动画流畅:按60fps更新,视觉效果平滑

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.24 16:02:41