停止计时器不起作用:



我在项目中有这个计时器。当它用完时,它显示了一个时间上屏幕,可以正常工作。但是,当玩家结束游戏时,我在屏幕上显示游戏,但是计时器保持运行,当它击中00:00时,它将切换到时间上屏幕。

如何使此计时器停止倒数并再次设置为00:00?

我尝试添加这样的函数:

CountDownTimer.prototype.stop = function() {
  diff = 0;
  this.running = false;    
};

我还试图更改InnerHTML,但很明显,它只是更改数字而不停止计时器,一秒钟后它将再次显示计数...我不知道该怎么称呼。

//Crazy Timer function start
function CountDownTimer(duration, granularity) {
  this.duration = duration;
  this.granularity = granularity || 1000;
  this.tickFtns = [];
  this.running = false;
}
CountDownTimer.prototype.start = function() {
  if (this.running) {
    return;
  }
  this.running = true;
  var start = Date.now(),
      that = this,
      diff, obj;
  (function timer() {
    diff = that.duration - (((Date.now() - start) / 1000) | 0);
    if (diff > 0) {
      setTimeout(timer, that.granularity);
    } else {
      diff = 0;
      that.running = false;
    }
    obj = CountDownTimer.parse(diff);
    that.tickFtns.forEach(function(ftn) {
      ftn.call(this, obj.minutes, obj.seconds);
    }, that);
  }());
};
CountDownTimer.prototype.onTick = function(ftn) {
  if (typeof ftn === 'function') {
    this.tickFtns.push(ftn);
  }
  return this;
};
CountDownTimer.prototype.expired = function() {
  return !this.running;
};
CountDownTimer.parse = function(seconds) {
  return {
    'minutes': (seconds / 60) | 0,
    'seconds': (seconds % 60) | 0
  };
};
window.onload = function () {
    var display = document.querySelector('#countDown'),
        timer = new CountDownTimer(timerValue),
        timeObj = CountDownTimer.parse(timerValue);
    format(timeObj.minutes, timeObj.seconds);
    timer.onTick(format).onTick(checkTime);
    document.querySelector('#startBtn').addEventListener('click', function () {
        timer.start();
    });
    function format(minutes, seconds) {
        minutes = minutes < 10 ? "0" + minutes : minutes;
        seconds = seconds < 10 ? "0" + seconds : seconds;
        display.textContent = minutes + ':' + seconds;
    }
    function checkTime(){
    if(this.expired()) {
        timeUp();
        document.querySelector('#startBtn').addEventListener('click', function () {
        timer.start();
    });
    }
    }
};

而不是递归调用setTimeout,而是尝试setInterval。然后,您可以存储对计时器的引用:

this.timer = setInterval(functionToRunAtInterval, this.granularity);

游戏结束后杀死它::

clearInterval(this.timer)

(有关SetInterval的更多信息,请参见MDN的文档)

已经有一段时间了,我不确定您是否弄清楚了,但请查看下面的小提琴: https://jsfiddle.net/f8rh3u85/1/

// until running is set to false the timer will keep running
if (that.running) {
    if (diff > 0) {
      setTimeout(timer, that.granularity);
    } else {
      diff = 0;
      that.running = false;
    }
    obj = CountDownTimer.parse(diff);
    that.tickFtns.forEach(function(ftn) {
      ftn.call(this, obj.minutes, obj.seconds);
    }, that);
}

我添加了一个导致运行设置为false的按钮,以停止计时器。

按钮:

<button id="stop">Game Over</button>

代码:

$( "#stop" ).click(function() {
    timer.running = false;
});

,希望您能将您带到您需要的地方。

与汤姆·詹金斯(Tom Jenkins)的回答相似,您需要通过避免使用if语句的diff > 0分支来取消下一个tick。您可以将代码保留在现状时并使用建议的stop方法,但是,您需要在处理刻度周围更改逻辑,以检查running === true和新的param gameOver === false

最终,我认为您的问题是,无论计时器是否运行,您都会始终在tick上执行此代码:

obj = CountDownTimer.parse(diff);
that.tickFtns.forEach(function(ftn) {
  ftn.call(this, obj.minutes, obj.seconds);
}, that);

如果您有一场游戏,则可能不想致电提供的回调,因此请在其中添加一些有条件的检查。

最新更新