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

countTo插件在Safari运行缓慢且速度配置失效兼容性问题

问题根源
  • 第一是浏览器的定时器强制节流规则:HTML标准明确要求,嵌套层级超过5层的setInterval/setTimeout最小触发间隔不得低于4ms,Safari对超短间隔定时器的节流策略比Chrome更严格,你代码中设置的refreshInterval:1(1ms触发一次)在Safari中实际触发间隔会被强制拉长到10~16ms,和设备屏幕刷新帧率对齐,远达不到设定的更新频率。
  • 第二是插件本身的逻辑缺陷:原有代码预先用speed/refreshInterval算出总更新次数,每次更新固定叠加一个步进值,完全依赖定时器的触发精度控制总动画时长。一旦定时器实际触发间隔偏离设定值,总时长就会完全失控。按你的配置,动画需要更新300次,若Safari中每次更新实际间隔为16ms,总时长就会达到4800ms,是预设300ms的16倍,直接表现为动画速度极慢、speed配置完全不生效。
修复方法

从两个维度调整即可解决全浏览器兼容性问题:

  1. 废弃固定步进+固定更新次数的实现逻辑,改为基于时间差计算动画进度:记录动画启动的高精度时间戳,每次更新时计算已流逝时长占总speed的比例,通过比例换算当前应该显示的数值,从根本上摆脱对定时器触发精度的依赖。
  2. 弃用1ms的超短刷新间隔,直接使用requestAnimationFrame驱动动画,和浏览器渲染帧率保持同步,性能更好,也不会触发定时器节流规则,Safari兼容性极佳。

修复后的完整插件代码如下:

(function($) {
  $.fn.countTo = function(options) {
    options = $.extend({}, $.fn.countTo.defaults, options || {});

    return $(this).each(function() {
      const el = this;
      const animStartTime = performance.now();
      const startVal = options.from;
      const endVal = options.to;
      const duration = options.speed;

      function frame(currentTime) {
        const elapsed = currentTime - animStartTime;
        const progress = Math.min(elapsed / duration, 1);
        const currentVal = startVal + (endVal - startVal) * progress;

        $(el).html(currentVal.toFixed(options.decimals));
        if (typeof options.onUpdate === 'function') {
          options.onUpdate.call(el, currentVal);
        }

        if (progress < 1) {
          requestAnimationFrame(frame);
        } else {
          if (typeof options.onComplete === 'function') {
            options.onComplete.call(el, endVal);
          }
        }
      }

      requestAnimationFrame(frame);
    });
  };

  $.fn.countTo.defaults = {
    from: 1.0,
    to: 2.0,
    speed: 300,
    decimals: 1,
    onUpdate: null,
    onComplete: null
  };
})(jQuery);

jQuery(function($) {
  $('.counter-up').countTo({
    from: 1.00,
    to: 2.00,
    decimals: 1,
    speed: 300
  });
});

原有HTML结构(jQuery引入、计数元素)不需要做任何修改。修复后动画会严格按照设定的speed时长完成,在Safari下的流畅度和速度表现和Chrome完全一致。

如果需要兼容IE9及以下不支持requestAnimationFrame的老旧浏览器,可以加简单polyfill回退到setInterval,注意将回退的刷新间隔设为16ms即可,不要使用小于10ms的间隔配置,避免触发浏览器节流。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.27 18:45:41