开发者

Plain JS countdown with repeat and delay

I keep running into several issues when creating a count开发者_如何转开发down script

  1. it does not run smoothly
  2. hard to make it repeat (closure)
  3. hard to delay the start and to delay the repeat (closure)

Can someone please help me FIX this code which should work in my opinion but doesn't

the processing I need is

a. counter starts delay number of seconds after the page loads,

b. when counter reaches 0, the countdown RE-starts after delay number of seconds

Here is my Fiddle

Issues:

  1. when it starts, the counter seems to wait an additional second before counting down
  2. it does not pause
  3. the repeat starts after the counter has continued

.

// 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)
}  


I've rewritten your code to produce the desired results. Your previous code was very inefficient. See my script comments for usage.

Fiddle: 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.
}  


Object exposing start([delay]) and 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);
};
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜