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

Plain JS countdown with repeat and delay

本文关键字:延迟 JS 倒计时 简单      更新时间:2023-09-26

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

  1. 运行不顺畅
  2. 难以重复(关闭)
  3. 难以延迟开始和延迟重复(关闭)

有人能帮我修复这个代码应该在我的意见工作,但没有

我需要的处理是

。计数器启动delay页面加载后的秒数,
b.当计数器到达0时,在延时秒数

后重新开始倒计时

这是我的小提琴

问题:

  1. 当它启动时,计数器似乎在倒数前等待额外的一秒
  2. 它不暂停
  3. 计数器继续后开始重复

.

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

我已经重写了您的代码以产生所需的结果。你以前的代码效率很低。参考我的脚本注释。

小提琴: 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.
}  

暴露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);
};