I have two demos, one with jQuery
and one without.
(我有两个演示,一个带有jQuery
,一个没有。)
Neither use date functions and are about as simple as it gets.(两者都不使用日期函数,并且都变得如此简单。)
Demo with vanilla JavaScript
(带有香草JavaScript的演示)
function startTimer(duration, display) { var timer = duration, minutes, seconds; setInterval(function () { minutes = parseInt(timer / 60, 10); seconds = parseInt(timer % 60, 10); minutes = minutes < 10 ? "0" + minutes : minutes; seconds = seconds < 10 ? "0" + seconds : seconds; display.textContent = minutes + ":" + seconds; if (--timer < 0) { timer = duration; } }, 1000); } window.onload = function () { var fiveMinutes = 60 * 5, display = document.querySelector('#time'); startTimer(fiveMinutes, display); };
<body> <div>Registration closes in <span id="time">05:00</span> minutes!</div> </body>
Demo with jQuery
(jQuery演示)
function startTimer(duration, display) {
var timer = duration, minutes, seconds;
setInterval(function () {
minutes = parseInt(timer / 60, 10);
seconds = parseInt(timer % 60, 10);
minutes = minutes < 10 ? "0" + minutes : minutes;
seconds = seconds < 10 ? "0" + seconds : seconds;
display.text(minutes + ":" + seconds);
if (--timer < 0) {
timer = duration;
}
}, 1000);
}
jQuery(function ($) {
var fiveMinutes = 60 * 5,
display = $('#time');
startTimer(fiveMinutes, display);
});
However if you want a more accurate timer that is only slightly more complicated:
(但是,如果您想要一个更精确的计时器,但只是稍微复杂一点:)
function startTimer(duration, display) { var start = Date.now(), diff, minutes, seconds; function timer() { // get the number of seconds that have elapsed since // startTimer() was called diff = duration - (((Date.now() - start) / 1000) | 0); // does the same job as parseInt truncates the float minutes = (diff / 60) | 0; seconds = (diff % 60) | 0; minutes = minutes < 10 ? "0" + minutes : minutes; seconds = seconds < 10 ? "0" + seconds : seconds; display.textContent = minutes + ":" + seconds; if (diff <= 0) { // add one second so that the count down starts at the full duration // example 05:00 not 04:59 start = Date.now() + 1000; } }; // we don't want to wait a full second before the timer starts timer(); setInterval(timer, 1000); } window.onload = function () { var fiveMinutes = 60 * 5, display = document.querySelector('#time'); startTimer(fiveMinutes, display); };
<body> <div>Registration closes in <span id="time"></span> minutes!</div> </body>
Now that we have made a few pretty simple timers we can start to think about re-usability and separating concerns.
(现在我们已经做了一些非常简单的计时器,我们可以开始考虑可重用性和分离关注点了。)
We can do this by asking "what should a count down timer do?"(我们可以通过问“倒数计时器应该做什么?”来做到这一点。)
- Should a count down timer count down?
(倒数计时器应该倒数吗?)
Yes(是)
- Should a count down timer know how to display itself on the DOM?
(倒数计时器应该知道如何在DOM上显示自己吗?)
No(没有)
- Should a count down timer know to restart itself when it reaches 0?
(倒数计时器是否应该知道在达到0时会自动重启?)
No(没有)
- Should a count down timer provide a way for a client to access how much time is left?
(倒数计时器是否应该为客户提供剩余时间的方式?)
Yes(是)
So with these things in mind lets write a better (but still very simple) CountDownTimer
(因此,请记住这些事情,让我们编写一个更好(但仍然非常简单)的CountDownTimer
)
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
};
};
So why is this implementation better than the others?
(那么,为什么这种实现比其他实现更好呢?)
Here are some examples of what you can do with it.(以下是一些您可以使用它的示例。)
Note that all but the first example can't be achieved by the startTimer
functions.(请注意,除了第一个示例以外的所有示例都无法通过startTimer
函数实现。)
An example that displays the time in XX:XX format and restarts after reaching 00:00
(一个以XX:XX格式显示时间并在到达00:00后重新启动的示例)
An example that displays the time in two different formats
(以两种不同格式显示时间的示例)
An example that has two different timers and only one restarts
(一个示例,其中有两个不同的计时器,只有一个重新启动)
An example that starts the count down timer when a button is pressed
(按下按钮时启动倒数计时器的示例)