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
相关产品推荐
相关产品推荐

