after reading “JavaScript: The Good Parts” of Douglas Crockford, I tried to implement a timer like this. It has private variable (seconds, hours, minutes) and three public methods: start, stop and continue:
var timer = function() {
var that = {};
var seconds = 0;
var hours = 0;
var minutes = 0;
var myTimer;
that.getTime = function() {
var time = hours + " : " + minutes + " : " + seconds;
return time;
}
that.start = function() {
seconds += 1;
if(seconds >= 60) {
seconds -= 60;
minutes += 1;
}
if(minutes == 60)
hours += 1;
document.getElementById('hours').innerHTML = hours;
document.getElementById('minutes').innerHTML = minutes;
document.getElementById('seconds').innerHTML = seconds;
myTimer = setTimeout(function() {
start();
}, 1000);
};
that.stop = function() {
clearTimeout(myTimer);
}
that.reset = function() {
seconds = 0;
hours = 0;
minutes = 0;
clearTimeout(myTimer);
document.getElementById('hours').innerHTML = hours;
document.getElementById('minutes').innerHTML = minutes;
document.getElementById('seconds').innerHTML = seconds;
}
return that;
};
and then, I started it:
<body onload="var t = timer();t.start();">
<h1>Digital Clock</h1>
<div id="wrap">
<div>
<ul>
<li id="hours"></li>
<li> : </li>
<li id="minutes"></li>
<li> : </li>
<li id="seconds"></li>
</ul>
</div>
</div>
<br/>
</body>
Can anyone tell me what errors did I make ?
Update: Finally, I found the problem.When you use a function from within another function (say, inner function), “this” is bound to global, not the outer function. Thus, in the statement start(), js will try to find a function in global object. Of course, there is no such function like this. Here, I found two solution:
-
use “that”
myTimer = setTimeout(function() {
that.start();
}, 1000); -
Save the context:
var timerInstance = this;
myTimer = setTimeout(function() {
timerInstance.start();
}, 1000);
Hope this will help you.
Here is a jsFiddle containing your modified code: http://jsfiddle.net/6YWLJ/
I’ve replaced “that” with “this” (“this” represents your timer) and instead of “var timer” i’ve used “window.timer”
Later edit: this is a version of corrected code, so it acts like a timer (you had some bugs in your code) http://jsfiddle.net/6YWLJ/2/