简单的JS倒计时,重复和延迟

时间:2011-09-27 09:40:20

标签: javascript settimeout setinterval

创建倒计时脚本时我一直遇到几个问题

  1. 运行不顺利
  2. 很难重复(关闭)
  3. 很难延迟开始并延迟重复(关闭)
  4. 有人可以请帮助我修复此代码,该代码应该在我看来有效,但不是

    我需要的处理是

    一个。计数器开始延迟页面加载后的秒数,
    湾当计数器达到0时,倒计时在延迟秒数后重新启动

    Here is my Fiddle

    的问题:

    1. 当它开始时,计数器似乎再等一下,然后倒计时
    2. 它不会暂停
    3. 在计数器继续后重复开始
    4. // more accurate timer - https://gist.github.com/1185904
      function interval(duration, fn){
        this.baseline = undefined
      
        this.run = function(){
          if(this.baseline === undefined){
            this.baseline = new Date().getTime()
          }
          fn()
          var end = new Date().getTime()
          this.baseline += duration
      
          var nextTick = duration - (end - this.baseline)
          if(nextTick<0){
            nextTick = 0
          }
          (function(i){
              i.timer = setTimeout(function(){
              i.run(end)
            }, nextTick)
          }(this))
        }
      
        this.stop = function(){
         clearTimeout(this.timer)
        }
      }
      window.onload=function() {
        var cnt1 = 10;
        var delay1 = 5;
        var timer1 = new interval(1000, function(){
          document.getElementById('out1').innerHTML=cnt1--
          if (cnt1 <= 0) { // trying to reset
            timer1.stop(); // does not work
            cnt1 = 10;
            setTimeout(function() { timer1.run()},delay1*1000)
          }
        })
        setTimeout(function() { timer1.run()},delay1*1000)
      }  
      

2 个答案:

答案 0 :(得分:2)

我重写了您的代码以产生所需的结果。您以前的代码效率很低。请参阅我的脚本注释以供使用。

小提琴http://jsfiddle.net/RVBDQ/1/

/*
  @name  timer
  @param number startFrom     Starts counting down from this number
  @param number delay         Seconds to wait before repeating the counter
  @param number intervalDelay Milliseconds between countdown
  @param number runTimes      Optional; Limit of counting. The function stops when it has run <runTimes> times. Default 1 (=one countdown)
  @param Boolean noFirstRun   Optional; If false, the counter starts off immediately. Default false
*/

function timer(startFrom, delay, intervalDelay, runTimes, notFirstRun){
    if(typeof runTimes == "undefined") runTimes = 1;
    if(runTimes-- < 0) return;
    setTimeout(function(){
        var ctn = startFrom;
        var timer1 = window.setInterval(function(){
            document.getElementById('out1').innerHTML = ctn--;
            if(ctn <= 0){
                clearInterval(timer1);
                timer(startFrom, delay, intervalDelay, runTimes, true);
            }

        }, intervalDelay);
    }, notFirstRun?delay*1000:0);
}
window.onload=function() {
    timer(10, 5, 1000, 2);
    //Runs two times, starts counting from 10 to 1, delays 5 seconds between counters.
}  

答案 1 :(得分:1)

对象公开start([delay])stop()

http://jsfiddle.net/RVBDQ/3/

function interval(duration, fn, delay){
    this.timer = null;
    this.duration = duration;
    this.fn = fn;

    this.start(delay);
}
interval.prototype.start = function(delay){
    if (this.timer) {return;}
    var self=this;
    this.timer = setTimeout(function(){ self.run(); }, delay||0);
};
interval.prototype.run = function(called){
    var self = this,
        nextTick = called ? this.duration - (new Date - called) : 0;

    this.timer = setTimeout(function(){
        self.fn();
        self.run(new Date);
    }, nextTick<0 ? 0 : nextTick);
};
interval.prototype.stop = function(){
    clearTimeout(this.timer);
    this.timer = null;
};

window.onload = function() {
    var cnt1 = 10;
    var delay1 = 5;
    window.timer1 = new interval(1000, function(){
        document.getElementById('out1').innerHTML=cnt1;
        cnt1 = cnt1 === 1 ? 10 : cnt1-1;
    }, delay1*1000);
};