停止计时器不工作:

时间:2015-05-12 13:52:02

标签: javascript timer

我的项目中有THIS计时器。 当它用完时,它会显示一个Time Up屏幕,工作正常。 但是当玩家玩游戏结束时,我会显示Game Over屏幕,但是计时器会继续运行,当它到达00:00时,它会切换到Time Up屏幕。

如何让这个计时器停止倒计时再次设置为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();
    });
    }
    }
};

3 个答案:

答案 0 :(得分:2)

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

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

并在游戏结束时将其杀死::

clearInterval(this.timer)

(有关setInterval的更多信息,请参阅MDN's docs

答案 1 :(得分:1)

已经有一段时间了,我不确定你是否已经弄明白但是看看下面的小提琴:     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;
});

所以这应该有希望让你到达你需要的地方。

答案 2 :(得分:0)

类似汤姆詹金斯&#39;回答,您需要通过避免if语句的diff > 0分支取消下一个tick。您可以按原样保留代码并使用建议的stop方法,但是,您需要更改处理滴答的逻辑,以检查running === true和新参数{{1 }}

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

gameOver === false

如果你有一个游戏结束状态,你可能不想调用提供的回调,所以在那里添加一些条件检查。