Link to home
Start Free TrialLog in
Avatar of FrankTech
FrankTech

asked on

Javascript Stopwatch Should Stop Counting While Paused

Please help me fix a problem in this JS stopwatch: unfortunately it does not stop counting while "paused."
     For example, if you let it count up to 1:59, and then pause it, and restart it 5 minutes later, it should resume at 2:00.  But it actually keeps counting while stopped, so it starts at 7:00.  
     What code can be changed to make it stop counting while paused, so that it will accurately resume where it left off?
<html>
<head>
<title>Javascript Stopwatch</title>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
<script LANGUAGE="JavaScript">
 var timerRunning = false;
 var timerID = null;
// create instance of Date object representing current time
 var initial = new Date();
 
// start timer
 function start_watch() {      
        // set the button's label to "stop"     
                document.forms['watch'].general.value = "stop";        
        // assign the stop function reference to the button's onClick event handler     
                document.forms['watch'].general.onclick = stop;        
       
	   /*
        // ask the user if to reset the timer   
               if (confirm("Would you like to reset the timer?")) {             
        // set global variable to new time              
               initial = new Date();
			   } 
	    */
      
        // assign milliseconds since 1970 to global variable    
                startTime = initial.getTime();   
        // make sure the timer is stopped       
                stopTimer(); 
        // run and display timer        
                showTimer();
}
 
// set button to initial settings
function stop() {       
        // set the button's label to "start"    
                document.forms['watch'].general.value = "start";       
        // assign the start_watch function reference to the button's onClick event handler    
                document.forms['watch'].general.onclick = start_watch;       
        // stop timer   
                stopTimer();
}
        // stop timer
function stopTimer() {  
        // if the timer is currently running    
                if (timerRunning)               
        // clear the current timeout (stop the timer)           
                clearTimeout(timerID)   
        // assign false to global variable because timer is not running 
                timerRunning = false
}
 
function showTimer() {  
        // create instance of Date representing current timer   
                var current = new Date();        
        // assign milliseconds since 1970 to local variable     
                var curTime = current.getTime(); 
        // assign difference in milliseconds since timer was cleared    
                var dif = curTime - startTime;           
        // assign difference in seconds to local variable       
                var result = dif / 1000; 
        // is result is not positive    
                if (result < 1)         
        // attach an initial "0" to beginning           
                result = "0" + result;           
        // convert result to string     
                result = result.toString();      
        // if result is integer 
                if (result.indexOf(".") == -1);          
        // attach ".00" to end          
                result += ".00"; 
        // is result contains only one digit after decimal point        
                if (result.length - result.indexOf(".") <= 2);           
        // add a second digit after point               
                result += "0";   
        // place result in text field   
                document.forms['watch'].display.value = result;        
        // call function recursively immediately (must use setTimeout to avoid overflow)        
                timerID = setTimeout("showTimer()", 0);  
        // timer is currently running   
                timerRunning = true;
}
</script>
</head>
 
<body bgcolor="#FFFFFF" text="#000000">
<form name="watch">
 <input TYPE="text" NAME="display" 
 onFocus="this.blur()" size="20">
 <input TYPE="button" NAME="general" VALUE="start"  onClick="start_watch();">
</form>
 
</body>
</html>

Open in new window

Avatar of Michel Plungjan
Michel Plungjan
Flag of Denmark image

Avatar of FrankTech
FrankTech

ASKER

I liked a feature of the script in my question, that it shows only one button, and automatically changes that one button to say "Start" or "Stop").
    But the Cool CountUp ( http://www.programsdb.com/script/936/25746/Cool_Countup.html ) already has the proper operation of stopping the count while paused.  (And it it's nice that it shows hours and minutes, not just seconds.)
     Maybe I'll use that one.  But I would like to have just one button that changes automatically to say "Start" or "Stop" or "Resume" like the code in my question (instead of having 4 separate buttons).
We are not allowed to change the source of that one.

Amazing how many of the scripts on the web has a pause button that does not work...

So perhaps I should write you one of my own...
OK. Yes, I just noticed the no-modifications copyright message on the CodeHouse script.  Thanks anyway.
     If you really do write your own, I would suggest that it have just one button (like the free script in my question) that changes automatically to say "Start", "Stop", or "Resume".  And if you really want to share it, it would be great to post it here as a comment, besides putting it on your personal Web site.
     For now, thanks for leading me to the CountUP script.
PS: I believe the stopwatch  you pasted cam from here
http://javascript-reference.info/stopwatch.htm
Yes, that looks like the page.  I forgot to bookmark it.  I didn't see any copyright or license of any kind, so I figured it was OK to modify freely.
    But the only good thing about that script is the single button.  It's great to have just one button that automatically changes its label and purpose from "Start", "Stop" or "Resume".  
   However, the CodeHouse script that you pointed out works better in other ways like showing hours, minutes, and seconds.
    So if you ever decide to write one yourself, I would humbly suggest that it would be nice to work like the CodeHouse script but have only one button like the other one.  
     Another great feature would be to make it possible to have multiple stopwatches on a page, in different table cells or divs, and clicking "Start" or "Resume" on any one would automatically "pause" the other ones.
    (Because this is good for people who want to track their time on multiple projects, and they realize their time can be devoted to only one task at a time--even though they say they can multitask. Because clicking "Start" or "Resume" on one timer should automatically pause the others, they would not have to remember to manually click "pause" on the others.)
     Just some suggestions on what I think this kind of script needs, in case you really do plan to write your own.

   There is a free script posted here on EE ( http:Q_21223865.html ID 12703291) that allows multiple stopwatches on a page, and it allows them to be started and stopped independently.  However, the time is not accurate on restart.
    It often looses track of the accurate timing when restarting after a pause.
     It's a simple script and you could probably modify it easily to fix the problems with time accuracy. It would be nice if it showed both minutes and seconds, too -- not just seconds.
<html>
<head>
<title>Multiple Javascript Stopwatches</title>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
<script>
function Timer(name,box){
 function startTimer(){
  this.d=new Date
  this.interval=setInterval(this.name+'.displaytimer()',1000)
 }
 
 function displaytimer(){
  now=new Date()
  secs=Math.round((now.getTime()-this.d.getTime())/1000)+this.seconds
  document.getElementById(this.box).value=secs
 }
 
 function reset(){
  clearInterval(this.interval)
  this.seconds=0
  document.getElementById(this.box).value=0
 }
 
 function stop(){
  this.seconds=Math.round((now.getTime()-this.d.getTime())/1000)
  clearInterval(this.interval)
  this.interval='null'
 }
 
 function restart(){
  if (this.interval=='null'){
   this.d=new Date
   this.interval=setInterval(this.name+'.displaytimer()',1000)
 }
}
 
 this.start=startTimer
 this.displaytimer=displaytimer
 this.stop=stop
 this.reset=reset
 this.restart=restart
 this.seconds=0
 this.name=name
 this.box=box
}
 
timer1=new Timer('timer1','timer1box')
timer2=new Timer('timer2','timer2box')
timer3=new Timer('timer3','timer3box')
</script>
 
<body>
 
 <input id="timer1box" value="0" size="3" style="font-size:16;border:2px solid red;text-align:right"><br>
 <input type="button" value="start" onclick="timer1.start()">
 <input type="button" value="reset" onclick="timer1.reset();"> 
 <input type="button" value="stop" onclick="timer1.stop();">
 <input type="button" value="restart" onclick="timer1.restart();"></p>
 
 
 <input id="timer2box" value="0" size="3" style="font-size:16;border:2px solid red;text-align:right"><br>
 <input type="button" value="start" onclick="timer2.start()">
 <input type="button" value="reset" onclick="timer2.reset();">
 <input type="button" value="stop" onclick="timer2.stop();">
 <input type="button" value="restart" onclick="timer2.restart();"></p>
 
 <input id="timer3box" value="0" size="3" style="font-size:16;border:2px solid red;text-align:right"><br>
 <input type="button" value="start" onclick="timer3.start()">
 <input type="button" value="reset" onclick="timer3.reset();"> 
 <input type="button" value="stop" onclick="timer3.stop();"> 
 <input type="button" value="restart" onclick="timer3.restart();"></p>
 
</body>
</html>

Open in new window

I'll have a look...

Javascript time is not always running smoothly, the clock is depending on the computer and displaying it is depending on other tasks running
Here is the last one with only one start/stop button
<input id="timer1box" value="0" size="3" style="font-size:16;border:2px solid red;text-align:right"><br>
 <input type="button" value="start"
 onclick="if (this.value=='start') { timer1.start(); this.value='stop'} else {timer1.stop(); this.value='start'}">
 <input type="button" value="reset" onclick="timer1.reset();">
 

<html>
<head>
<title>Multiple Javascript Stopwatches</title>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
<script>
function Timer(name,box){
 function startTimer(){
  this.d=new Date
  this.interval=setInterval(this.name+'.displaytimer()',1000)
 }
 
 function displaytimer(){
  now=new Date()
  secs=Math.round((now.getTime()-this.d.getTime())/1000)+this.seconds
  mins = parseInt(secs/60)
  secs -=(mins*60);
  document.getElementById(this.box+'Mins').value=(mins<10)?"0"+mins:mins;
  document.getElementById(this.box+'Secs').value=(secs<10)?"0"+secs:secs;
 }
 
 function reset(){
  clearInterval(this.interval)
  this.seconds=0
  document.getElementById(this.box).value=0
 }
 
 function stop(){
  this.seconds=Math.round((now.getTime()-this.d.getTime())/1000)
  clearInterval(this.interval)
  this.interval='null'
 }
 
 function restart(){
  if (this.interval=='null'){
   this.d=new Date
   this.interval=setInterval(this.name+'.displaytimer()',1000)
 }
}
 
 this.start=startTimer
 this.displaytimer=displaytimer
 this.stop=stop
 this.reset=reset
 this.restart=restart
 this.seconds=0
 this.name=name
 this.box=box
}
 
timer1=new Timer('timer1','timer1box')
//timer2=new Timer('timer2','timer2box')
//timer3=new Timer('timer3','timer3box')
</script>
 
<body>
 
 <input id="timer1boxMins" value="0" size="3" style="font-size:16;border:2px solid red;text-align:right">:
 <input id="timer1boxSecs" value="0" size="3" style="font-size:16;border:2px solid red;text-align:right"><br>
 <input type="button" value="start" 
 onclick="if (this.value=='start') { timer1.start(); this.value='stop'} else {timer1.stop(); this.value='start'}">
 <input type="button" value="reset" onclick="timer1.reset();"><br><br> 
 
 <!--
 <input id="timer2box" value="0" size="3" style="font-size:16;border:2px solid red;text-align:right"><br>
 <input type="button" value="start" onclick="timer2.start()">
 <input type="button" value="reset" onclick="timer2.reset();">
 <input type="button" value="stop" onclick="timer2.stop();">
 <input type="button" value="restart" onclick="timer2.restart();"><br><br>
 
 <input id="timer3box" value="0" size="3" style="font-size:16;border:2px solid red;text-align:right"><br>
 <input type="button" value="start" onclick="timer3.start()">
 <input type="button" value="reset" onclick="timer3.reset();"> 
 <input type="button" value="stop" onclick="timer3.stop();"> 
 <input type="button" value="restart" onclick="timer3.restart();"><br><br>
 -->
</body>
</html>

Open in new window

That's great.  Thanks.
     Did you notice the timing problem?  It loses several seconds when restarting after a pause.
     For example, when I paused this one at 36 seconds, it restarted at only 21 seconds.
    When I stopped it at 2:02 , it restarted at 1:43.
    (But the CodeHouse script that you linked was always accurate when it restarted after a pause. I wonder how they did it so accurately?)

    Also, it is possible to make all other clocks stop (and their buttons change to say "Start") when any one clock is started?  For example, if Clock 1 is running, and then I click "Start" for Clock 3, then Clock 1 should pause and its button should turn to "Start". (And although there should never be multiple clocks running, it probably should check to make sure *all* other clocks are stopped and their buttons say "Start", when any one clock's Start button is clicked.)  I would be very grateful if that is possible. Thank you.
I'll have a look later - perhaps this weekend
OK. I'll look forward to that.
I really appreciate your expert help.
I worked on your original posted code. I believe it is working as you expect it.
<html>
<head>
<title>Javascript Stopwatch</title>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
<script LANGUAGE="JavaScript">
 var timerRunning = false;
 var timerID = null;
// create instance of Date object representing current time
 var initial = new Date();
 
// start timer
 function start_watch() {      
        // set the button's label to "stop"     
                document.forms['watch'].general.value = "stop";        
        // assign the stop function reference to the button's onClick event handler     
                document.forms['watch'].general.onclick = stop;        
       
	   /*
        // ask the user if to reset the timer   
               if (confirm("Would you like to reset the timer?")) {             
        // set global variable to new time              
               initial = new Date();
			   } 
	    */
		initial=new Date();
		if( document.forms['watch'].display.value )
		{
			var t = String(document.forms['watch'].display.value).split(".");
			initial.setSeconds( initial.getSeconds() - parseInt(t[0]) );
			initial.setMilliseconds( initial.getMilliseconds() - parseInt(t[1]) );
		}
        // assign milliseconds since 1970 to global variable    
                startTime = initial.getTime();   
        // make sure the timer is stopped       
                stopTimer(); 
        // run and display timer        
                showTimer();
}
 
// set button to initial settings
function stop() {
        // set the button's label to "start"    
                document.forms['watch'].general.value = "start";       
        // assign the start_watch function reference to the button's onClick event handler    
                document.forms['watch'].general.onclick = start_watch;       
        // stop timer   
                stopTimer();
}
        // stop timer
function stopTimer() {  
        // if the timer is currently running    
                if (timerRunning)               
        // clear the current timeout (stop the timer)           
                clearTimeout(timerID)   
        // assign false to global variable because timer is not running 
                timerRunning = false
			 //var t = new Date();
	 //initial = new Date(initial.valueOf() + (t.valueOf() - initial.valueOf()) );
}
 
function showTimer() {  
        // create instance of Date representing current timer   
               var current = new Date(); 
 
        // assign milliseconds since 1970 to local variable     
                var curTime = current.getTime(); 
        // assign difference in milliseconds since timer was cleared    
                var dif = curTime - startTime;           
        // assign difference in seconds to local variable       
                var result = dif / 1000; 
        // is result is not positive    
                if (result < 1)         
        // attach an initial "0" to beginning           
                result = "0" + result;           
        // convert result to string     
                result = result.toString();      
        // if result is integer 
                if (result.indexOf(".") == -1);          
        // attach ".00" to end          
                result += ".00"; 
        // is result contains only one digit after decimal point        
                if (result.length - result.indexOf(".") <= 2);           
        // add a second digit after point               
                result += "0";   
        // place result in text field   
                document.forms['watch'].display.value = result;        
        // call function recursively immediately (must use setTimeout to avoid overflow)        
                timerID = setTimeout("showTimer()", 10);  
        // timer is currently running   
                timerRunning = true;
}
</script>
</head>
 
<body bgcolor="#FFFFFF" text="#000000">
<form name="watch">
 <input TYPE="text" NAME="display" 
 onFocus="this.blur()" size="20">
 <input TYPE="button" NAME="general" VALUE="start"  onClick="start_watch();">
</form>
 
</body>
</html>

Open in new window

hielo,
     Thank you!  Your solution seems to work exactly as requested in my question.  Could you briefly explain how this accurate pause works?      
      Also, I wonder if the time display could be easily modified to have less precision in the display (without decreasing the accuracy), because my application won't need to show milliseconds.  E.g., how could I change it to show:
      152.597  instead of 152.597.000  
I don't see where the script is adding all the 000's.
      Or would it be possible to show only the seconds (e.g. 153) or the seconds.tenths (e.g. 152.6 ) instead of 152.597.000 (without decreasing the accuracy of the counting)?
Good one Hielo - you really want to be #1 huh?

PS: Rename watch and display since they are reserved words
mplungjan,
   Although  hielo  would get the points on this question (since he answered the specific original question), I'm opening a new 500-point question for you to provide the solution you've been looking at, for multiple stopwatches on one page, with accurate pause, and each watch's buttons turning from start to stop automatically. Please see http:Q_23115854.html . Thanks.
>> Could you briefly explain how this accurate pause works?
The original script was always computing the difference in time from the point that the script loaded. That's why you had:
var intial = new Date();
declared at a global scope. Basically I just reset that variable every time the clock is restarted and make time adjustments to it based on the elapsed time so that the difference would be computed correctly.

>>Also, I wonder if the time display could be easily modified to have less precision in the display
Actually, the last ".000" never change. I left there because it was there. Didn't want to mess with your app. But I removed it. For the sake of accuracy, you are better of leaving the milliseconds.
<html>
<head>
<title>Javascript Stopclock</title>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
<script LANGUAGE="JavaScript">
 var timerRunning = false;
 var timerID = null;
// create instance of Date object representing current time
 var initial = new Date();
 
// start timer
 function start_clock() {      
        // set the button's label to "stop"     
                document.forms['clock'].general.value = "stop";        
        // assign the stop function reference to the button's onClick event handler     
                document.forms['clock'].general.onclick = stop;        
       
	   /*
        // ask the user if to reset the timer   
               if (confirm("Would you like to reset the timer?")) {             
        // set global variable to new time              
               initial = new Date();
			   } 
	    */
		initial=new Date();
		if( document.forms['clock'].displayScreen.value )
		{
			var t = String(document.forms['clock'].displayScreen.value).split(".");
			initial.setSeconds( initial.getSeconds() - parseInt(t[0]) );
			initial.setMilliseconds( initial.getMilliseconds() - parseInt(t[1]) );
		}
        // assign milliseconds since 1970 to global variable    
                startTime = initial.getTime();   
        // make sure the timer is stopped       
                stopTimer(); 
        // run and displayScreen timer        
                showTimer();
}
 
// set button to initial settings
function stop() {
        // set the button's label to "start"    
                document.forms['clock'].general.value = "start";       
        // assign the start_clock function reference to the button's onClick event handler    
                document.forms['clock'].general.onclick = start_clock;       
        // stop timer   
                stopTimer();
}
        // stop timer
function stopTimer() {  
        // if the timer is currently running    
                if (timerRunning)               
        // clear the current timeout (stop the timer)           
                clearTimeout(timerID)   
        // assign false to global variable because timer is not running 
                timerRunning = false
			 //var t = new Date();
	 //initial = new Date(initial.valueOf() + (t.valueOf() - initial.valueOf()) );
}
 
function showTimer() {  
        // create instance of Date representing current timer   
               var current = new Date(); 
 
        // assign milliseconds since 1970 to local variable     
                var curTime = current.getTime(); 
        // assign difference in milliseconds since timer was cleared    
                var dif = curTime - startTime;           
        // assign difference in seconds to local variable       
                var result = dif / 1000; 
        // is result is not positive    
                if (result < 1)         
        // attach an initial "0" to beginning           
                result = "0" + result;           
        // convert result to string     
                result = result.toString();
        // place result in text field   
                document.forms['clock'].displayScreen.value = result;        
        // call function recursively immediately (must use setTimeout to avoid overflow)        
                timerID = setTimeout("showTimer()", 0);  
        // timer is currently running   
                timerRunning = true;
}
</script>
</head>
 
<body bgcolor="#FFFFFF" text="#000000">
<form name="clock">
 <input TYPE="text" NAME="displayScreen" 
 onFocus="this.blur()" size="20">
 <input TYPE="button" NAME="general" VALUE="start"  onClick="start_clock();">
</form>
 
</body>
</html> 

Open in new window

hielo,
    Thanks. I agree keeping the milliseconds will lead to better accuracy, but is it possible to change how the clock displays when paused?
    In other words, the script could use (and could even show) milliseconds when counting, but when the user presses "Stop" the textbox display would show the time as rounded to the nearest second, and also show hours and minutes?
     I think I just need a function that fires when the "Stop" button is clicked. It would take the string of seconds and milliseconds, and format it differently to display in the textbox. For example:
   72.032   would appear as 00:01:12  (1 minute and 12 seconds).
   306.50  would appear as 00:05:07  (5 minutes and 7 seconds, if I figured it right).
    This is because a number like 1337439 seconds might be accurate (and should be used by the script internally), but it would be clearer to a human to see a display like 06:11:31  (six hours, 11 minutes, and 31 seconds).
    Is it possible for the script to use milliseconds internally for timekeeping, but display "human-readable" format in the textbox?  

I found an algorithm (on this site) to do the conversion (see the code snippet), if you could show me how to use it in the stopwatch script.
function miliToSeconds(x)
{
      var intHours;
      var intMinutes;
      var intSeconds;
 
      var strHours="00";
      var strMinutes="00";
      var strSeconds="00";
      var strTime;
 
            intTimeElapsed=x; // get the time elapsed
 
            // Calculations to convert from milliseconds into standard 0:00:00 time format
            intTimeElapsed=Math.floor(intTimeElapsed/1000); // round down to the nearest 
 
integer, and divide by 1000 to convert to seconds
            intHours=Math.floor(intTimeElapsed/3600); // get hours (3600 seconds / hour)
            intMinutes=Math.floor(intTimeElapsed/60); // get minutes (60 seconds / minite)
            intSeconds=(intTimeElapsed%60); // get seconds (total seconds modulus 60)
 
            strHours=intHours;
            strMinutes=intMinutes;
            strSeconds=intSeconds;
 
            // insert zeros in front of time elapsed where necissary ( < 10 ) to preserve 
 
hh:mm:ss format
            if (intSeconds < 10)
                  strSeconds="0" + strSeconds;
            if (intMinutes < 10)
                  strMinutes="0" + strMinutes;
            if (intHours < 10)
                  strHours="0" + strHours;
 
            strTime=strHours + ":" + strMinutes + ":" + strSeconds; // create time string
            return strTime;
}

Open in new window

Here you go:
<html>
<head>
<title>Javascript Stopclock</title>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
<script LANGUAGE="JavaScript">
 var timerRunning = false;
 var timerID = null;
// create instance of Date object representing current time
 var initial = new Date();
 
// start timer
 function start_clock() {      
        // set the button's label to "stop"     
                document.forms['clock'].general.value = "stop";        
        // assign the stop function reference to the button's onClick event handler     
                document.forms['clock'].general.onclick = stop;        
       
		initial=new Date();
		if( document.forms['clock'].displayScreen.value )
		{
			var t1 = String(document.forms['clock'].displayScreen.value).split(".");
			var t2 = t1[0].split(":");
			initial.setSeconds( initial.getSeconds() - parseInt(t2[2]) );
			initial.setMilliseconds( initial.getMilliseconds() - parseInt(t1[1]) );
			t1=t2=null;
		}	
        // assign milliseconds since 1970 to global variable    
                startTime = initial.getTime();   
        // make sure the timer is stopped       
                stopTimer(); 
        // run and displayScreen timer        
                showTimer();
}
 
// set button to initial settings
function stop() {
        // set the button's label to "start"    
                document.forms['clock'].general.value = "start";       
        // assign the start_clock function reference to the button's onClick event handler    
                document.forms['clock'].general.onclick = start_clock;       
        // stop timer   
                stopTimer();
}
        // stop timer
function stopTimer() {  
        // if the timer is currently running    
                if (timerRunning)               
        // clear the current timeout (stop the timer)           
                clearTimeout(timerID)   
        // assign false to global variable because timer is not running 
                timerRunning = false
}
 
function showTimer() {  
        // create instance of Date representing current timer   
               var current = new Date(); 
 
        // assign milliseconds since 1970 to local variable     
                var curTime = current.getTime(); 
        // assign difference in milliseconds since timer was cleared    
                var dif = curTime - startTime;           
        // assign difference in seconds to local variable       
                var result = dif / 1000; 
        // is result is not positive    
                if (result < 1)         
        // attach an initial "0" to beginning           
                result = "0" + result;           
        // convert result to string     
                result = result.toString();
			 var hrs = parseInt(result/3600);
			 var mins = parseInt(result/60);
			 var secs = (result%1000);
			 hrs = (hrs < 10) ? "0" + hrs: hrs;
			 mins = (mins < 10) ? "0" + mins: mins;
			 secs = String(secs).split(".");
			 var milli = (secs[1] || "000");
			 milli = (milli.length == 3) ? milli : (milli.length==2 ? milli + "0":milli+"00");
			 var secs = (parseInt(secs[0]) < 10) ? "0" + secs[0] : secs[0];
        // place result in text field   
                document.forms['clock'].displayScreen.value = hrs+":"+mins+":"+secs+"."+milli;   
 
        // call function recursively immediately (must use setTimeout to avoid overflow)        
                timerID = setTimeout("showTimer()", 10);  
        // timer is currently running   
                timerRunning = true;
}
</script>
</head>
 
<body bgcolor="#FFFFFF" text="#000000">
<form name="clock">
 <input TYPE="text" NAME="displayScreen" value="00:00:00.000"
 onFocus="this.blur()" size="20">
 <input TYPE="button" NAME="general" VALUE="start"  onClick="start_clock();">
</form>
 
</body>
</html>  

Open in new window

For the sake of accuracy, on the last post, change:
                timerID = setTimeout("showTimer()", 10);
to
                timerID = setTimeout("showTimer()", 0);

Also, the following line needs updated from this:
var secs = (parseInt(secs[0]) < 10) ? "0" + secs[0] : secs[0];

to this:
var secs = (parseInt(secs[0]%60) < 10) ? "0" + secs[0]%60 : secs[0]%60;

The code below is the same as the previous but without the milliseconds:
<html>
<head>
<title>Javascript Stopclock</title>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
<script LANGUAGE="JavaScript">
 var timerRunning = false;
 var timerID = null;
// create instance of Date object representing current time
 var initial = new Date();
 
// start timer
 function start_clock() {      
        // set the button's label to "stop"     
                document.forms['clock'].general.value = "stop";        
        // assign the stop function reference to the button's onClick event handler     
                document.forms['clock'].general.onclick = stop;        
       
		initial=new Date();
		if( document.forms['clock'].displayScreen.value )
		{
			var t1 = String(document.forms['clock'].displayScreen.value).split(".");
			var t2 = t1[0].split(":");
			initial.setSeconds( initial.getSeconds() - parseInt(t2[2]) );
 
			t1=t2=null;
		}	
        // assign milliseconds since 1970 to global variable    
                startTime = initial.getTime();   
        // make sure the timer is stopped       
                stopTimer(); 
        // run and displayScreen timer        
                showTimer();
}
 
// set button to initial settings
function stop() {
        // set the button's label to "start"    
                document.forms['clock'].general.value = "start";       
        // assign the start_clock function reference to the button's onClick event handler    
                document.forms['clock'].general.onclick = start_clock;       
        // stop timer   
                stopTimer();
}
        // stop timer
function stopTimer() {  
        // if the timer is currently running    
                if (timerRunning)               
        // clear the current timeout (stop the timer)           
                clearTimeout(timerID)   
        // assign false to global variable because timer is not running 
                timerRunning = false
}
 
function showTimer() {  
        // create instance of Date representing current timer   
               var current = new Date(); 
 
        // assign milliseconds since 1970 to local variable     
                var curTime = current.getTime(); 
        // assign difference in milliseconds since timer was cleared    
                var dif = curTime - startTime;           
        // assign difference in seconds to local variable       
                var result = dif / 1000; 
        // is result is not positive    
                if (result < 1)         
        // attach an initial "0" to beginning           
                result = "0" + result;           
        // convert result to string     
                result = result.toString();
			 var hrs = parseInt(result/3600);
			 var mins = parseInt(result/60);
			 var secs = (result%1000);
			 hrs = (hrs < 10) ? "0" + hrs: hrs;
			 mins = (mins < 10) ? "0" + mins: mins;
			 secs = String(secs).split(".");
			 var secs = (parseInt(secs[0]%60) < 10) ? "0" + secs[0]%60 : secs[0]%60;
        // place result in text field   
                document.forms['clock'].displayScreen.value = hrs+":"+mins+":"+secs;   
 
        // call function recursively immediately (must use setTimeout to avoid overflow)        
                timerID = setTimeout("showTimer()", 0);  
        // timer is currently running   
                timerRunning = true;
}
</script>
</head>
 
<body bgcolor="#FFFFFF" text="#000000">
<form name="clock">
 <input TYPE="text" NAME="displayScreen" value="00:00:00"
 onFocus="this.blur()" size="20">
 <input TYPE="button" NAME="general" VALUE="start"  onClick="start_clock();">
</form>
 
</body>
</html>  

Open in new window

hielo,
   Fantastic! That seems to work perfectly.  Thank you!

I'm accepting your solution; and please look at another question ( http:Q_23117375.html ) to follow up on this one, where I'm asking how to modify your final version to use it like an object to easily use several of these stopwatches on one page.  
    The goal is to have any number of your scripts running at once, using an object-type setup sort of like the setup shown in # 20743125 above. And when the Start button is clicked on any of the clocks, any others should automatically stop/pause (and their buttons should turn to "Start"). Please see the 500-point question at http:Q_23117375.html . Thanks!
hielo,
   I just discovered a problem.
I tested counting up to 00:01:29 and pausing.  When I came back later, it started at 00:00:00 instead of 00:01:30.
     Also, I tried going to 00:01:06 . When I paused and later restarted, it started at 00:00:07 instead of 00:01:07.  It's loosing track of time while paused.  (It didn't seem to have that problem before adding the hours:minutes:seconds display. Perhaps something in that algorithm needs adjustment?)
hielo,
   Here's another test:  I let it count up to 00:11:39 . Then I paused it.
   A few minutes later I resumed.  Instead of starting at 00:11:40, it started at 00:00:40 .

    Please help me figure out the bug. Thanks.
ASKER CERTIFIED SOLUTION
Avatar of hielo
hielo
Flag of Wallis and Futuna image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Thanks!  I'm testing it now.
   But one more minor issue I noticed with the previous version:  when the previous script got to 1 hour, 0 minutes, and 24 seconds, it displayed:
       01:60:24
instead of:
       01:00:24.
And I guess   01:01:00  would look like  01:61:00 , etc. (but I stopped it before reaching there).

    Does the latest version probably fix that issue, too?  (I'll run it for an hour just to make sure before marking the solution "accepted.")
    Thanks for your patience.  The script is getting really excellent!
hielo,
    Wonderful !  I tested it over 1 hour, and it seems to show the hours, minutes, and seconds properly now because of the revision you made in ID 20763212.
   It went from   00:59:59  to  01:00:00  as it should.
Thank for your great expertise, and thank you for sticking with this question to the happy end.
hielo,
   If you see this, I just noticed another problem:

     When the time goes past 1 hour, the time is not accurate when resuming after a pause.  

For example:
     -  I stopped it at 01:05:17.   When I resumed, it started at 01:05:06  instead of 01:05:18.
      -  When stopped at 01:17:23, it resumed at 01:17:43 instead of 01:17:44.
      -  When stopped at 1:17:45, it restarted at 01:17:05.

Example of another problem
     -  When running at  01:18:59, the next number was  01:18:00  instead of  01:19:00.

     -  When running from 01:19:59, it went to 01:19:00 , and counted up to 01:19:20 ; then it changed to 01:20:21.

Since this question is closed, I'm asking for help to fix this problem as part of the new question:  http:Q_23117375.html . Thanks
>> If you see this, I just noticed another problem:
Typically I do testing but with other things going on, I left the testing up to you!

>>  When the time goes past 1 hour
You mean you let it run for an hour. LOL. Cruel punishment! I'll take a look at it later. I will make time adjustments so I don't sit for a whole hour!!!
Thanks hielo,
    Right; I found it quite boring to sit and test it for so long, but it will be used in a situation where it could run for several hours, and/or will be stopped and started frequently, so I just wanted to make sure it's accurate.   If you want to visit the new question ( http:Q_23117375.html ), I have reported more details of the timing problems there, up to 2 hours. Thanks again.