我想在Javascript中创建一个简单的计时器,从给定时间开始倒计时直到达到0.我发现这个tutorial完美无缺。我的问题是我需要在同一页面上放置多个计时器。本教程显然不会这样做,因为它使用全局变量(我是JS / Programming的新手,所以我可能没有使用正确的术语)。我试图重新创建相同的东西,只创建每个计时器,因为它自己的对象,以便它们不会互相干扰。这就是我所拥有的。
function taskTimer(name, startTime) {
this.timer = name;
this.totalSeconds = startTime;
this.tick = function() {
if (this.totalSeconds <= 0) {
return;
}
this.totalSeconds -= 1;
this.updateTimer();
// window.setTimeout("this.tick()", 1000);
};
this.updateTimer = function(){
this.seconds = this.totalSeconds;
this.hours = Math.floor(this.seconds / 3600);
this.seconds -= this.hours * (3600);
this.minutes = Math.floor(this.seconds / 60);
this.seconds -= this.minutes * (60);
this.timeString = this.leadingZero(this.hours) + ":" + this.leadingZero(this.minutes) + ":" + this.leadingZero(this.seconds);
return this.timeString;
};
this.leadingZero = function(time){
return (time < 10) ? "0" + time : + time;
};
}
var testTimer = new taskTimer("timer", 30);
testTimer.tick();
我在那里创造了一个。运行
testTimer.updateTimer();
返回00:00:30
这是正确的,但运行testTimer.tick();
不会返回任何值。这部分代码显然有些问题我无法理解。
答案 0 :(得分:4)
你遇到了一些问题。
updateTimer()
方法中调用了tick
,所以它
除非你归还,否则不会到达那里。tick
,如果每隔一秒钟没有这样做,则定时器将不准确。 totalSeconds
,因为不能保证你的超时触发之间只有一秒。请改用日期。以下是我要做的事:http://jsfiddle.net/R4hnE/3/
// I added optional callbacks. This could be setup better, but the details of that are negligible.
function TaskTimer(name, durationInSeconds, onEnd, onTick) {
var endTime,
self = this, // store a reference to this since the context of window.setTimeout is always window
running = false;
this.name = name;
this.totalSeconds = durationInSeconds;
var go = (function tick() {
var now = new Date().getTime();
if (now >= endTime) {
if (typeof onEnd === "function") onEnd.call(self);
return;
}
self.totalSeconds = Math.round((endTime - now) / 1000); // update totalSeconds placeholder
if (typeof onTick === "function") onTick.call(self);
window.setTimeout(tick, 1000 / 12); // you can increase the denominator for greater accuracy.
});
// this is an instance method to start the timer
this.start = function() {
if (running) return; // prevent multiple calls to start
running = true;
endTime = new Date().getTime() + durationInSeconds * 1000; // this is when the timer should be done (with current functionality. If you want the ability to pause the timer, the logic would need to be updated)
go();
};
}
// no reason to make this an instance method :)
TaskTimer.prototype.toTimeString = function() {
var hrs = Math.floor(this.totalSeconds / 60 / 60),
min = Math.floor(this.totalSeconds / 60 - hrs * 60),
sec = this.totalSeconds % 60;
return [hrs.padLeft("0", 2), min.padLeft("0", 2), sec.padLeft("0", 2)].join(" : ");
};
var task = new TaskTimer("task1", 30, function() {
document.body.innerHTML = this.toTimeString();
alert('done');
}, function() {
document.body.innerHTML = this.toTimeString();
});
答案 1 :(得分:0)
我总是遇到this
的问题,在一个例子中,在函数中,我不得不重新定义它:
this.tick = function() {
self=this;
if (self.totalSeconds <= 0) {
return;
}
self.totalSeconds -= 1;
self.updateTimer();
// window.setTimeout("self.tick()", 1000);
};
以下是另一篇文章:var self = this?
答案 2 :(得分:0)
我的版本,你可以看到: http://fiddle.jshell.net/hmariod/N7haK/4/
var tmArray = new Array();
var timerRef, timerId=0;
function newTimer(){
try{
if(tmArray.length > 4) throw "Too much timers";
var countDown = parseInt(document.getElementById("tCountown").value,10);
if(isNaN(countDown)) throw "tCountown is NaN";
var tmName = document.getElementById("tName").value;
var nt = new taskTimer(++timerId, tmName, countDown);
createTmElement(timerId, tmName);
tmArray.push(nt);
if(!timerRef) timerRef = setInterval(timerFn, 1000);
showTimers();
}catch(er){
alert("newTimer:" + er);
}
}
function taskTimer(id, name, tCountown) {
this.id = id;
this.tName = name;
this.tCountown = tCountown;
}
function timerFn(){
try{
var i;
killTimer = true;
for(i = 0; i < tmArray.length; i++){
tmArray[i].tCountown--;
if(tmArray[i].tCountown < 0){
tmArray[i].tCountown = 0;
}else{
killTimer = false;
}
}
if(killTimer) clearInterval(timerRef);
showTimers();
}catch(er){
clearInterval(timerRef);
aler("timerFn: " + er);
}
}