Entry
How do I code a stop watch?
Sep 5th, 2004 15:08
Knud van Eeden, Martin Honnen,
Not much of a DHTML problem, as far as the functionality of the watch
is considered but as I show an example to display the time inside a
table cell I put this entry under DHTML.
The first script block in the code below implements a StopWatch
constructor function with which StopWatch objects can be instantiated.
The constructor takes a function as an argument which is later called
to display the actual time or otherwise consume the time components of
the watch.
The body of the HTML page contains two example watch displays, one in
a form that should work with NN4+ and IE4+, the other inside a table
cell which should work with IE4+ and NN6+.
<html>
<head>
<title>
stop watch
</title>
<script type="text/javascript">
function StopWatch (showTime) {
this.id = StopWatch.watches.length;
StopWatch.watches[this.id] = this;
this.showTime = typeof showTime == 'function' ? showTime : function
() {};
this.reset();
}
StopWatch.prototype.reset = function () {
this.time = 0;
this.components = {};
this.computeComponents();
this.showTime(this.components);
}
StopWatch.prototype.start = function () {
this.tid = setTimeout('StopWatch.watches[' + this.id + '].run()',
1000);
}
StopWatch.prototype.stop = function () {
clearTimeout(this.tid);
}
StopWatch.prototype.run = function () {
this.tid = setTimeout('StopWatch.watches[' + this.id + '].run()',
1000);
this.time++;
this.computeComponents();
this.showTime(this.components);
}
StopWatch.prototype.computeComponents = function () {
var hours = Math.floor(this.time / StopWatch.secondsPerHour);
var remainingTime = this.time - hours * StopWatch.secondsPerHour;
var minutes = Math.floor(remainingTime / StopWatch.secondsPerMinute);
var seconds = remainingTime - minutes * StopWatch.secondsPerMinute;
var formattedTime = '';
formattedTime += hours + ':';
formattedTime += minutes < 10 ? '0' + minutes + ':' : minutes + ':';
formattedTime += seconds < 10 ? '0' + seconds : seconds;
this.components.time = this.time;
this.components.hours = hours;
this.components.minutes = minutes;
this.components.seconds = seconds;
this.components.formattedTime = formattedTime;
}
StopWatch.secondsPerMinute = 60;
StopWatch.secondsPerHour = StopWatch.secondsPerMinute * 60;
StopWatch.watches = new Array();
</script>
<script type="text/javascript">
function showTimeFormWatch (components) {
document.watch0.time.value =
components.formattedTime;
}
var stopWatch;
</script>
<style type="text/css">
input.time {
font-family: 'Courier New', monospace;
}
</style>
<script type="text/javascript"> if (!document.layers)
document.write(
'<style type="text/css">input.time { text-align: right; }<\/style>'
);
</script>
<script type="text/javascript">
var stopWatch2;
function showTimeTableWatch (components) {
if (document.all)
document.all.timeCell.innerText = components.formattedTime;
else if (document.getElementById)
document.getElementById('timeCell').firstChild.nodeValue =
components.formattedTime;
}
</script>
<style type="text/css">
td.time {
font-family: 'Courier New', monospace;
font-weight: bold;
background-color: lightblue;
color: orange;
}
</style>
</head>
<body>
<form name="watch0">
<input type="button"
value="start"
onclick="stopWatch.start();"
/>
<input type="button"
value="stop"
onclick="stopWatch.stop();"
/>
<input type="button"
value="reset"
onclick="stopWatch.reset();"
/>
<input type="text" size="9" readonly="readonly"
name="time" class="time"
/>
</form>
<script type="text/javascript">
stopWatch = new StopWatch(showTimeFormWatch);
</script>
<table border="0">
<tr>
<td id="timeCell" class="time" align="center"
valign="middle"> </td>
</tr>
<tr>
<td>
<input type="button"
value="start"
onclick="stopWatch2.start();"
/>
<input type="button"
value="stop"
onclick="stopWatch2.stop();"
/>
<input type="button"
value="reset"
onclick="stopWatch2.reset();"
/>
</td>
</tr>
</table>
<script type="text/javascript">
stopWatch2 = new StopWatch(showTimeTableWatch);
</script>
</body>
</html>
I didn't test this thoroughly, in particular I have not taken the time
to test whether the computation of hours works so if you want to use
this and expect the watch to run for more than an hour then better
test that case.