【问题标题】:jQuery counter to count up to a target numberjQuery计数器计数到目标数字
【发布时间】:2011-02-02 04:10:21
【问题描述】:

我正在尝试找出是否有人知道一个已经存在的 jQuery 插件,该插件将以指定的速度计数到目标数。

例如,查看 Google 在 Gmail homepage 上“大量空间”标题下的可用存储 MB 数。它在<span> 标签中有一个起始数字,并且每秒缓慢地向上计数。

我正在寻找类似的东西,但我希望能够指定:

  • 起始编号
  • 结束编号
  • 从开始到结束应该花费的时间。
  • 可以在计数器完成时执行的自定义回调函数。

【问题讨论】:

    标签: jquery jquery-plugins timer counter


    【解决方案1】:

    我最终创建了自己的插件。这是以防万一这对任何人都有帮助:

    (function($) {
        $.fn.countTo = function(options) {
            // merge the default plugin settings with the custom options
            options = $.extend({}, $.fn.countTo.defaults, options || {});
            
            // how many times to update the value, and how much to increment the value on each update
            var loops = Math.ceil(options.speed / options.refreshInterval),
                increment = (options.to - options.from) / loops;
            
            return $(this).each(function() {
                var _this = this,
                    loopCount = 0,
                    value = options.from,
                    interval = setInterval(updateTimer, options.refreshInterval);
                
                function updateTimer() {
                    value += increment;
                    loopCount++;
                    $(_this).html(value.toFixed(options.decimals));
                    
                    if (typeof(options.onUpdate) == 'function') {
                        options.onUpdate.call(_this, value);
                    }
                    
                    if (loopCount >= loops) {
                        clearInterval(interval);
                        value = options.to;
                        
                        if (typeof(options.onComplete) == 'function') {
                            options.onComplete.call(_this, value);
                        }
                    }
                }
            });
        };
        
        $.fn.countTo.defaults = {
            from: 0,  // the number the element should start at
            to: 100,  // the number the element should end at
            speed: 1000,  // how long it should take to count between the target numbers
            refreshInterval: 100,  // how often the element should be updated
            decimals: 0,  // the number of decimal places to show
            onUpdate: null,  // callback method for every time the element is updated,
            onComplete: null,  // callback method for when the element finishes updating
        };
    })(jQuery);
    

    下面是一些如何使用它的示例代码:

    <script type="text/javascript"><!--
        jQuery(function($) {
            $('.timer').countTo({
                from: 50,
                to: 2500,
                speed: 1000,
                refreshInterval: 50,
                onComplete: function(value) {
                    console.debug(this);
                }
            });
        });
    //--></script>
    
    <span class="timer"></span>
    

    在 JSFiddle 上查看演示:http://jsfiddle.net/YWn9t/

    【讨论】:

    • 如果有人有任何改进建议,我将这段代码移至 Github:github.com/mhuggins/jquery-countTo
    • 仅供参考 - 此插件可在以下位置获得改进:github.com/mhuggins/jquery-countTo
    • 如何在滚动时启动计数器?
    • 是否有任何选项可以让计数器在滚动时再次触发??
    • 这个计数器太棒了,我们如何操纵它来动态更新/增加最终的“to”数量并在更新时恢复计算。
    【解决方案2】:

    你可以使用jQuery animate函数

    $({ countNum: 0 }).animate({ countNum: 10 }, {
      duration: 10000, // tune the speed here
      easing: 'linear',
      step: function() {
        // What todo on every count
        console.log(this.countNum);
      },
      complete: function() {
        console.log('finished');
      }
    });
    &lt;script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"&gt;&lt;/script&gt;

    【讨论】:

    • 值得注意的是,这似乎并不完美。我在 Chrome 中运行了您的 jsbin 示例,结果不一致地以 998 或 999 而不是 1000 结束。
    • 这是因为 Math.floor()。如果您尝试删除 floor() 函数,您将在每一步得到正确的数字,即 1000 / 8000 = 0,125。我相信除了最后一步之外的每一步都执行“步骤:”动作 - 女巫是“完成:”事件
    • 很公平。我想complete 方法可以更新以包含这一行,以确保它到达最后一个数字:$('#counter').text(this.countNum);
    • 请问我该如何让数字带有逗号和两位小数,就好像它是价格一样?
    • this.countNum.toFixed(2)替换Math.floor(this.countNum)
    【解决方案3】:

    我已经创建了最小的代码来做到这一点。它不仅用于计数,还用于需要在给定时间内运行的任何任务。 (比方说,做某事 5 秒):

    演示:

    var step = function(t, elapsed){
        // easing 
        t = t*t*t;
    
        // calculate new value
        var value = 300 * t; // will count from 0 to 300
    
        // limit value ("t" might be higher than "1")
        if( t > 0.999 )
            value = 300;
    
        // print value (converts it to an integer)
        someElement.innerHTML = value|0;
    };
    
    var done = function(){
        console.log('done counting!');
    };
    
    
    // Do-in settings object
    var settings = {
        step     : step,
        duration : 3,
        done     : done,
        fps      : 24 // optional. Default is requestAnimationFrame
    };
    
    // initialize "Do-in" instance 
    var doin = new Doin(settings);
    

    【讨论】:

      【解决方案4】:

      不知道插件,但这应该不会太难:

      ;(function($) {        
           $.fn.counter = function(options) {
              // Set default values
              var defaults = {
                  start: 0,
                  end: 10,
                  time: 10,
                  step: 1000,
                  callback: function() { }
              }
              var options = $.extend(defaults, options);            
              // The actual function that does the counting
              var counterFunc = function(el, increment, end, step) {
                  var value = parseInt(el.html(), 10) + increment;
                  if(value >= end) {
                      el.html(Math.round(end));
                      options.callback();
                  } else {
                      el.html(Math.round(value));
                      setTimeout(counterFunc, step, el, increment, end, step);
                  }
              }            
              // Set initial value
              $(this).html(Math.round(options.start));
              // Calculate the increment on each step
              var increment = (options.end - options.start) / ((1000 / options.step) * options.time);            
              // Call the counter function in a closure to avoid conflicts
              (function(e, i, o, s) {
                  setTimeout(counterFunc, s, e, i, o, s);
              })($(this), increment, options.end, options.step);
          }
      })(jQuery);
      

      用法:

      $('#foo').counter({
          start: 1000,
          end: 4500,
          time: 8,
          step: 500,
          callback: function() {
              alert("I'm done!");
          }
      });
      

      例子:

      http://www.ulmanen.fi/stuff/counter.php

      我猜这个用法是不言自明的;在本例中,计数器将从 1000 开始,以 500ms 的间隔在 8 秒内计数到 4500,并在计数完成时调用回调函数。

      【讨论】:

        【解决方案5】:

        我不知道任何现有的插件,但使用JavaScript Timing Events 自己编写一个似乎相当容易。

        【讨论】:

        • 是的,如果我必须写一个,我认为我不会有问题,但我宁愿使用现有的来节省时间并尽可能处理错误问题。
        • 您可以从字面上使用他发送给您的页面上的那个。这是一个无限循环。只需相应调整即可。
        • 确实 :) 我想功能(和代码)太简单了,无法在没有太多开销的情况下将其变成有用的插件。
        【解决方案6】:

        另一种方法。使用 Tween.js 作为计数器。当计数器到达目标位置时,它可以让计数器减速、加速、弹跳和许多其他好处。

        http://jsbin.com/ekohep/2/edit#javascript,html,live

        享受:)

        PS,不使用 jQuery - 但显然可以。

        【讨论】:

          【解决方案7】:

          需要休息一下,所以我拼凑了以下内容。不确定是否值得创建一个插件。

          <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
          <html xmlns="http://www.w3.org/1999/xhtml">
              <head>
                  <title>
                      Counter
                  </title>
                  <script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.4.2/jquery.js"></script>
                  <script type="text/javascript">
                      //<![CDATA[
                          function createCounter(elementId,start,end,totalTime,callback)
                          {
                              var jTarget=jQuery("#"+elementId);
                              var interval=totalTime/(end-start);
                              var intervalId;
                              var current=start;
                              var f=function(){
                                  jTarget.text(current);
                                  if(current==end)
                                  {
                                      clearInterval(intervalId);
                                      if(callback)
                                      {
                                          callback();
                                      }
                                  }
                                  ++current;
                              }
                              intervalId=setInterval(f,interval);
                              f();
                          }
                          jQuery(document).ready(function(){
                              createCounter("counterTarget",0,20,5000,function(){
                                  alert("finished")
                              })
                          })
                      //]]>
                  </script>
              </head>
              <body>
                  <div id="counterTarget"></div>
              </body>
          </html>
          

          【讨论】:

            【解决方案8】:

            试试jCounter,它有一个 customRange 设置,您可以在其中指定开始和结束编号,它也可以计数,包括最后您想要的回退。

            【讨论】:

            • 链接已损坏。
            【解决方案9】:

            不使用 jQuery 的另一种方法是使用 Greensock 的 TweenLite JS 库。

            演示http://codepen.io/anon/pen/yNWwEJ

            var display = document.getElementById("display");
            var number = {param:0};
            var duration = 1;
            
            function count() {
              TweenLite.to(number, duration, {param:"+=20", roundProps:"param",
              onUpdate:update, onComplete:complete, ease:Linear.easeNone});
            }
            
            function update() {
              display.innerHTML = number.param;
            }
            
            function complete() {
              //alert("Complete");
            }
            
            count();
            

            【讨论】:

              【解决方案10】:

              代码笔Working Example

              更多 GitHub repo

              <!DOCTYPE html>
              <html>
              <head>
                  <title>Count Up Numbers Example</title>
                  <script src="https://code.jquery.com/jquery-2.2.4.js" integrity="sha256-iT6Q9iMJYuQiMWNd9lDyBUStIq/8PuOW33aOqmvFpqI=" crossorigin="anonymous"></script>
              
                  <style type="text/css">
                      /* 
                      Courtesy: abcc.com
                      https://abcc.com/en
                      https://abcc.com/en/at-mining 
                      */
                      .rewards {
                          background-color: #160922;
                      }
              
                      .th-num-bold {
                          font-family: "Arial" ;
                      }
              
                      .ff-arial {
                          font-family: "Arial" ;
                      }
              
                      .scroll-wrap .scroll-exchange-fee .exchange_time {
                          color: hsla(0,0%,100%,.7);
                          font-size: 13px;
                      }
              
                      .f14 {
                          font-size: 14px;
                      }
              
                      .flex {
                          display: -webkit-box;
                          display: -ms-flexbox;
                          display: flex;
                      }
              
                      .jcsb {
                          -ms-flex-pack: justify!important;
                          -webkit-box-pack: justify!important;
                          justify-content: space-between!important;
                      }
              
                      .aic {
                          -ms-flex-align: center!important;
                          -webkit-box-align: center!important;
                          align-items: center!important;
                      }
              
              
                      li {
                          list-style: none;
                      }
              
                      .pull-left {
                          float: left!important;
                      }
              
                      .rewards-wrap {
                          height: 100%;
                      }
              
                      .at-equity-wrap .rewards .calculate_container {
                          -webkit-box-shadow: rgba(0,0,0,.03) 0 5px 10px 0;
                          background: url(https://s.abcc.com/portal/static/img/home-bg-pc.c9207cd.png);
                          background-repeat: no-repeat;
                          background-size: 1440px 100%;
                          box-shadow: 0 5px 10px 0 rgba(0,0,0,.03);
                          margin: 0 auto;
                          max-width: 1200px;
                          overflow: hidden;
                          position: relative;
                      }
              
                      .rewards-pc-wrap .current-profit .point {
                          color: #fff;
                          font-size: 25px;
                      }
              
                      .rewards-pc-wrap .current-profit .integer {
                          color: #fff;
                          font-size: 45px;
                      }
              
                      .rewards-pc-wrap .current-profit .decimal {
                          color: #fff;
                          font-size: 25px;
                      }
              
                      .rewards-pc-wrap .current-profit .unit {
                          color: #fff;
                          font-size: 24px;
                          margin-right: 5px;
                          margin-top: 18px;
                      }
              
                      .rewards-pc-wrap .yesterday-profit .point {
                          color: #fff;
                          font-size: 25px;
                      }
              
                      .rewards-pc-wrap .yesterday-profit .integer {
                          color: #fff;
                          font-size: 45px;
                      }
              
                      .rewards-pc-wrap .yesterday-profit .decimal {
                          color: #fff;
                          font-size: 25px;
                      }
              
                      .rewards-pc-wrap .yesterday-profit .unit {
                          color: #fff;
                          font-size: 24px;
                          margin-right: 5px;
                          margin-top: 18px;
                      }
              
                      .rewards-pc-wrap .profit-rate-100 .point {
                          color: #fff;
                          font-size: 25px;
                      }
              
                      .rewards-pc-wrap .profit-rate-100 .integer {
                          color: #fff;
                          font-size: 45px;
                      }
              
                      .rewards-pc-wrap .profit-rate-100 .decimal {
                          color: #fff;
                          font-size: 25px;
                      }
              
                      .rewards-pc-wrap .profit-rate-100 .unit {
                          color: #fff;
                          font-size: 24px;
                          margin-right: 5px;
                          margin-top: 18px;
                      }
              
                      .rewards-pc-wrap .total-profit .point {
                          color: #fff;
                          font-size: 25px;
                      }
              
                      .rewards-pc-wrap .total-profit .integer {
                          color: #fff;
                          font-size: 45px;
                      }
              
                      .rewards-pc-wrap .total-profit .decimal {
                          color: #fff;
                          font-size: 25px;
                      }
              
                      .rewards-pc-wrap .total-profit .unit {
                          color: #fff;
                          font-size: 24px;
                          margin-right: 5px;
                          margin-top: 18px;
                      }
              
                      .rewards-pc-wrap {
                          height: 400px;
                          margin-left: 129px;
                          padding-top: 100px;
                          width: 630px;
                      }
              
                      .itm-rv {
                          -ms-flex: 1;
                          -webkit-box-flex: 1;
                          flex: 1;
                          font-family: "Arial";
                      }
              
                      .fb {
                          font-weight: 700;
                      }
              
                      .main-p {
                          color: hsla(0,0%,100%,.7);
                          font-size: 13px;
                          margin-bottom: 8px;
                          margin-top: 10px;
                      }
              
                      .sub-p {
                          color: hsla(0,0%,100%,.5);
                          font-size: 12px;
                          margin-top: 12px;
                      }
              
                      .fb-r {
                          font-weight: 300;
                      }
              
                      .price-btc {
                          color: hsla(0,0%,100%,.5);
                          font-size: 13px;
                          margin-top: 10px;
                      }
              
                  </style>
              </head>
              <body>
                  <div class="at-equity-wrap">
                      <div  class="rewards" >
                          <div  class="calculate_container">
                              <div  class="rewards-wrap">
                                  <div class="flex jcc aic">
                                      <div  class="rewards-pc-wrap slideInUp" id="nuBlock">
                                          <div  class="flex jcsb aic">
                                              <div  class="itm-rv" style="margin-right: 60px;">
                                                  <div  class="current-profit th-num-bold fb"><span  class="unit pull-left">$</span> <span class="integer" id="cr_prft_int" >0</span> <span  class="point">.</span> <span class="decimal" id="cr_prft_dcml" >00</span></div>
                                                  <p  class="main-p">Platform Rewards to Be Distributed Today</p>
                                                  <p  class="sub-p fb-r">Total circulating KAT eligible for rewards:100,000,000</p>
                                              </div>
                                              <div  class="itm-rv">
                                                  <div  class="profit-rate-100 th-num-bold"><span  class="unit pull-left">$</span> <span  class="integer" id="dly_prft_int" >0</span> <span  class="point">.</span><span  class="decimal" id="dly_prft_dcml" >00</span></div>
                                                  <p  class="main-p">Daily Rewards of 1000 KAT</p>
                                                  <div  class="profit-rate sub-p fb-r"><span >Daily KAT Rewards Rate</span> <span  class="integer">0</span> <span  class="decimal">.00</span> <span  class="unit">%</span></div>
                                              </div>
                                          </div>
                                          <div  class="flex jcsb aic" style="margin-top: 40px;">
                                              <div  class="itm-rv" style="margin-right: 60px;">
                                                  <div  class="yesterday-profit th-num-bold fb'"><span  class="unit pull-left">$</span> <span  class="integer" id="ytd_prft_int" >0</span> <span  class="point">.</span><span  class="decimal" id="ytd_prft_dcml" >00</span></div>
                                                  <div  class="price-btc fb-r">/ 0.00000000 BTC</div>
                                                  <p  class="main-p fb-r">Platform Rewards Distributed Yesterday</p>
                                              </div>
                                              <div  class="itm-rv">
                                                  <div  class="total-profit th-num-bold fb'"><span  class="unit pull-left">$</span> <span  class="integer" id="ttl_prft_int" >0</span> <span  class="point">.</span><span  class="decimal" id="ttl_prft_dcml" >00</span></div>
                                                  <div  class="price-btc fb-r">/ 0.00000000 BTC</div>
                                                  <p  class="main-p fb-r">Cumulative Platform Rewards Distributed</p>
                                              </div>
                                          </div>
                                      </div>
                                  </div>
                              </div>
                          </div>
                      </div>
                  </div>
              </body>
              <script type="text/javascript">
              
                  $(document).on('ready', function(){
              
                      setTimeout(function(){ 
                          cr_countUp();
                          dly_countUp();
                          ytd_countUp();
                          ttl_countUp();
                      }, 2000);
              
                  });
              
                  unit = "$";
              
                  var cr_data, dly_data, ytd_data, ttl_data;
                  cr_data = dly_data = ytd_data = ttl_data = ["670.0000682", "670.002", "660.000068", "660.002", "650.000000063", "650.01", "640.00000006", "640.01", "630.0000000602", "630.01", "620.0000000622", "620.01", "610.00000016", "610.002", "600.00000015998", "600.002", "590.00000094", "590.002", "580.0000009", "580.002", "760.0000682", "760.002", "660.000068", "660.002", "560.000000063", "560.01", "460.00000006", "460.01", "360.0000000602", "360.01", "260.0000000622", "260.01", "160.00000016", "160.002", "060.00000015998", "060.002", "950.00000094", "950.002", "850.0000009", "850.002"];
              
                  cr_start = 0;
                  cr_stop = cr_data.length - 1;
                  cr_nu = 20;
              
                  function cr_countUp(){
                      setTimeout(function(){
                          $("#cr_prft_int").text(cr_data[cr_start].split(".")[0]);
                          $("#cr_prft_dcml").text(cr_data[cr_start].split(".")[1]);
                          if(cr_start < cr_stop){
                              cr_start += 1;
                              cr_countUp();
                          }
                      }, cr_nu);
                  }
              
                  dly_start = 0;
                  dly_stop = dly_data.length - 1;
                  dly_nu = 20;
              
                  function dly_countUp(){
                      setTimeout(function(){
                          $("#dly_prft_int").text(dly_data[dly_start].split(".")[0]);
                          $("#dly_prft_dcml").text(dly_data[dly_start].split(".")[1]);
                          if(dly_start < dly_stop){
                              dly_start += 1;
                              dly_countUp();
                          }
                      }, dly_nu);
                  }
              
                  ytd_start = 0;
                  ytd_stop = ytd_data.length - 1;
                  ytd_nu = 20;
              
                  function ytd_countUp(){
                      setTimeout(function(){
                          $("#ytd_prft_int").text(ytd_data[ytd_start].split(".")[0]);
                          $("#ytd_prft_dcml").text(ytd_data[ytd_start].split(".")[1]);
                          if(ytd_start < ytd_stop){
                              ytd_start += 1;
                              ytd_countUp();
                          }
                      }, ytd_nu);
                  }
              
                  ttl_start = 0;
                  ttl_stop = ttl_data.length - 1;
                  ttl_nu = 20;
              
                  function ttl_countUp(){
                      setTimeout(function(){
                          $("#ttl_prft_int").text(ttl_data[ttl_start].split(".")[0]);
                          $("#ttl_prft_dcml").text(ttl_data[ttl_start].split(".")[1]);
                          if(ttl_start < ttl_stop){
                              ttl_start += 1;
                              ttl_countUp();
                          }
                      }, ttl_nu);
              
                  }
              </script>
              </html>
              
              

              【讨论】:

                【解决方案11】:

                您可以为此使用 jquery animate 函数。

                $({ countNum: $('.code').html() }).animate({ countNum: 4000 }, {
                        duration: 8000,
                        easing: 'linear',
                        step: function () {
                        $('.code').html(Math.floor(this.countNum) );
                        },
                        complete: function () {
                        $('.code').html(this.countNum);
                        //alert('finished');
                        }
                    });
                

                这是original article

                【讨论】:

                  猜你喜欢
                  • 1970-01-01
                  • 2021-03-09
                  • 1970-01-01
                  • 2021-09-04
                  • 1970-01-01
                  • 1970-01-01
                  • 2012-10-05
                  • 1970-01-01
                  • 2018-11-07
                  相关资源
                  最近更新 更多