【问题标题】:Animated numbers (semi-countdown) with JQuery?带有 JQuery 的动画数字(半倒计时)?
【发布时间】:2009-10-26 21:47:41
【问题描述】:

我正在尝试使用 JQuery 制作一个数值,比如 5000,然后快速更改为另一个值,比如 4000。现在我可以很好地使用:

mod(".class",4000,"add");

function mod(id,value,type){
    var numb = $(id).html();
    var current_value = parseInt(numb);
    do {
        if(type == "add")
            increment(id);
        else
            decrement(id);
        current_value = parseInt(numb);
    }while(current_value != value);

    function decrement(id){
        $(id).html(current_value-1);
    }

    function increment(id){
        $(id).html(current_value+1);
    }
}

我知道这可能不是最好的方法,但我需要它做的是从当前值快速倒计时(或向上)数字到设定值。我使用这种方法的目的是使用 setInterval 或 setTimeout 进行延迟,但这会使整个脚本严重失败。

感谢任何建议,但我不希望为这个看似简单的任务使用大型插件。

【问题讨论】:

  • 看起来您的目标是提供可见的倒计时或向上显示。除了代码效率,您提供的代码看起来很实用。你所拥有的有什么问题?

标签: jquery numbers jquery-animate countdown


【解决方案1】:

您在这里所做的是快速连续多次更新 DOM。结果,浏览器将等到您完成所有更改,然后才会重新绘制页面。因此,在数字一直下降到 4000 之前,您不会看到任何视觉变化。

是的,您确实需要使用setTimeoutsetInterval / clearInterval。或者,为了代码的清晰,你可以使用jQuery "wait" plugin:

// (code to get new value goes here)

$('.class').wait(100, function(){
    $(this).text(newValue);
});

我使用了text() 而不是html(),因为看起来您不需要更改任何HTML 结构。

【讨论】:

    【解决方案2】:

    当我运行您提供的代码时,我陷入了无限循环。在 do 循环结束时,您有

    current_value = parseInt(numb);

    但是 numb 的值只设置在函数的开头,所以它一直持续下去。如果您将其更改为

    current_value = parseInt($(id).html());

    然后它工作正常。除了它似乎是立即发生的。

    我破解了一种使用超时实现动画的方法,似乎效果很好,但由于我对 javascript 还很陌生,我不知道是否有更有效的方法。只需调整传递给 setTimeout 的第二个参数即可获得所需的速度。而如果你想改变增量/减量值,只需改变dir的减速度即可。

    function mod2(id, value) {
        var numb = $(id).html();
        var current_value = parseInt(numb);
    
        // determine direction to go
        var dir = 1;
        if (current_value - value > 0) {
            dir *= -1;
        }
        getThere(id, current_value, value, dir);
    }
    
    function getThere(id, current_value, target_value, dir) {
        current_value += dir;
        $(id).html(current_value);
        if (current_value != target_value) {
            setTimeout("getThere('"+id+"',"+current_value+","+target_value+","+dir+")", 10);
        }
    }
    

    【讨论】:

      【解决方案3】:

      我喜欢 thorn 的 setTimeout 方法,但我会将其压缩为 2 个函数并在窗口加载后启动它,以确保在更新计数器之前页面已加载:

      var counterTimeout = 10; // time between increments in ms
      $(window).load(function() {
          mod('class', 'add', 4000);
      });
      
      function mod(class, type, targetVal) {
          var $class = $(class);
          var numb = parseInt($class.html());
          numb = (type == 'add') ? numb + 1 : numb - 1;
          $class.html(numb);
          if (numb != targetVal) {
              setTimeout('mod("' + class + '","' + type + '",' + targetVal)', counterTimeout);
          }
      }
      

      如果 $class.html() 以高于 targetVal 的值(在 'add' 的情况下或低于 targetVal 在其他情况下的值开始),则基本情况不满足。在进行函数调用之前,您必须确保不会发生这种情况。

      【讨论】: