Pausing a stopwatch does not stop the time - javascript

Hopefully I can make myself clear here.
I am using the following code to run my stopwatch:
function timecounter(starttime)
{
currentdate = new Date();
details = document.getElementById('details');
stopwatch = document.getElementById('stopwatch');
var timediff = currentdate.getTime() - starttime;
if(runningstate == 0)
{
timediff = timediff + stoptime
}
if(runningstate == 1)
{
stopwatch.value = formattedtime(timediff);
refresh = setTimeout('timecounter(' + starttime + ');',10);
}
else
{
window.clearTimeout(refresh);
stoptime = timediff;
}
}
function startandstop()
{
var startandstop = document.getElementById('startandstopbutton');
if(runningstate==0)
{
startandstop.value = 'Pause';
runningstate = 1;
timecounter(starttime);
}
else
{
startandstop.value = 'Start';
runningstate = 0;
lapdate = '';
}
}
But when I select the button to pause the time, the time stops, but when I press start again, it jumps to the time that it currently is as if I had not pause the time.
I have been trying to figure out what's going on with it and have come to no success.
I believe that it might have something to do with the timecounter() function but from there I am not certain.
Any help would be greatly appreciated!
Thanks,
Brandon

I think you should use .performance.now() if you want something close to accurate in terms of ms.
Thought you had an interesting problem so I came up with a solution of my own for fun. Hope it helps. :) (UPDATES BELOW THE CODE)
http://jsfiddle.net/colbycallahan/CjDz7/1/ (cleaned it up a bit for display and rounding a bit)
Works and Requires jQuery:
HTML:
<div id="console"></div>
<input type="button" id="btn" value="start time">
<input type="button" id="btn2" value="stop time">
js:
var timerRunning = false;
var startTime;
var totalTime;
$('#console').data('totalTime', 0);
function startTimer(){
totalTime = $('#console').data('totalTime');
startTime = window.performance.now();
timerRunning = true;
function timerLoop(){
window.setTimeout(function(){
if(timerRunning){
$('#console').text(window.performance.now() - startTime + totalTime);
timerLoop();
}
}, 50);
}
timerLoop();
}
$('#btn').on('click', function(){
startTimer();
});
$('#btn2').on('click', function(){
totalTime = window.performance.now() - startTime + totalTime;
$('#console').data('totalTime', totalTime);
timerRunning = false;
});
I took your code and the first thing I did was fix what can possibly cause errors in terms of syntax regarding curly braces on separate lines from if statement, missing semicolon in the if statement for when running state is 0, one semicolon incorrectly placed in timecounter() call. You tried to call a function by making it a string, but strings never call functions. starttime is not defined before you pass it as an argument to timecounter(). Your settimeout() line should be set up outside the condition statement to call it. You unnecessarily call an else if running state is not 1. lapdate is not defined other than to make it empty string. Also refresh is not defined unless running state is 1, but is only called when refresh does not equal 1. Lastly you did not include all of the code necessary to know if additional mistakes were made nor is there enough code to know if what I rewrote will fix your issue, which is why I wrote new code(it requires jquery library to be included on your page). I don't really understand the logic of your code. One more thing: you will need to retrieve the stored value of elapsed time after a user has started timer, clicked pause, and then resumed the timer. As a thanks, you should go to JSLint.com or similar and never run your code in a browser until it passes a lint test. I am only reposting your code at the bottom and don't expect it to work. I redid my timer in vanilla javascript with no jquery required. It is here:
Works and Requires no jQuery:
<!DOCTYPE html>
<html>
<head>
</head>
<body>
<div id="console"></div>
<input type="button" id="btn" value="start time" onclick="startTimer();">
<input type="button" id="btn2" value="stop time" onclick="stopTimer();">
<input type="hidden" id="storedTime" value="0">
<script>
var timerRunning = false;
var startTime;
var totalTime;
var storedTimeInp = document.getElementById('storedTime');
var console = document.getElementById('console');
function startTimer(){
totalTime = Number(storedTimeInp.value, 10);
startTime = window.performance.now();
timerRunning = true;
function timerLoop(){
window.setTimeout(function(){
if(timerRunning){
console.innerHTML = (window.performance.now() - startTime + totalTime);
timerLoop();
}
}, 50);
}
timerLoop();
}
function stopTimer(){
totalTime = window.performance.now() - startTime + totalTime;
storedTimeInp.value = totalTime;
timerRunning = false;
}
</script>
</body>
</html>
Your Code Rewritten Kinda(broken):
var runningstate = 0;
function timecounter(starttime){
currentdate = new Date();
details = document.getElementById('details');
stopwatch = document.getElementById('stopwatch');
var timediff = currentdate.getTime() - starttime;
setTimeout(
if(runningstate == 0){
timediff = timediff + stoptime;
}else{
stopwatch.value = formattedtime(timediff);
timecounter(starttime);
stoptime = timediff;
}
,10);
}
function startandstop(){
var startandstop = document.getElementById('startandstopbutton');
if(runningstate==0){
startandstop.value = 'Pause';
runningstate = 1;
starttime = new Date();
starttime = starttime.getTime();
timecounter(starttime);
}else{
startandstop.value = 'Start';
runningstate = 0;
lapdate = '';
}
}

Related

Javascript clearInterval is not having an effect?

I am trying to do a simple redirect after x seconds on a page with a countdown timer. Every time I call the function I want the timer to be reset, however when i call it a second or third time the timer seems to have 3 different countdowns. Can anyone see why this is?
function delayRedirect(){
document.getElementById('countDown').innerHTML = 'Session Timeout In: <span id="countTimer"></span> seconds....';
clearInterval(sessionTimer);
var sessionTimer = null;
var timeleft = 60;
var sessionTimer = setInterval(function(){
timeleft--;
document.getElementById('countTimer').innerHTML = timeleft;
if(timeleft <= 0)
clearInterval(sessionTimer);
returnToLogin();
},1000);
}
Put the sessionTimer globally. What you currently do is re-declare sessionTimer every time you enter delayRedirect.
Working example:
const but = document.getElementById("but");
but.addEventListener("click", delayRedirect);
//define it globally
var sessionTimer = -1;
function delayRedirect() {
//clear it if it previously exists
clearInterval(sessionTimer);
sessionTimer = setInterval(function() {
console.log("sessionTimer " + sessionTimer);
}, 1000);
}
<button id="but">Run</button>
I feel like all the answers only address the Y part, not the X part, given that this is clearly an XY problem.
While the solution is to use a variable that isn't local to the function, solving the actual problem doesn't require clearing anything. One can simply use an interval to tick down, and reset the count to delay the redirect:
var timeleft = 60;
setInterval(function() {
if (--timeleft === 0) returnToLogin();
countTimer.innerHTML = timeleft;
}, 1000);
delay.onclick = function() {
timeleft = 60;
}
function returnToLogin() {
console.log("returning to login");
}
<p>Session Timeout In: <span id="countTimer">60</span> seconds....</p>
<button id="delay">Delay</button>

Stopwatch in JavaScript

Before marking the question duplicate, I want to tell that I have been through all the stopwatch and JavaScript searches but as I am new to the JavaScript, so I can not come to the possible solution myself and I need the help from you guys.
What I want to achieve is to start and stop the watch with the same button. I can stop the watch but can not start again, can't figure out why.
Have a look at the following script and correct me.
var startTimer = setInterval(function(){myTimer()}, 1000);
function myTimer(){
var current = new Date();
document.getElementById("timer").innerHTML = current.toLocaleTimeString();
}
function start(st){
// Problem is in this statement
// How can I call the global function variable again that's startTimer
window[st]();
var elem = document.getElementById("myButton");
elem.innerHTML = "Stop";
elem.addEventListener("click", stop);
}
function stop(){
clearInterval(startTimer);
var elem = document.getElementById("myButton");
elem.innerHTML = "Start";
elem.addEventListener("click", start(startTimer));
}
<p id="timer"></p>
<button id="myButton" onclick="stop(startTimer)">Stop</button>
You want a single method to take care of the start/stop:
var startTimer = setInterval(myTimer, 1000),
timerElement = document.getElementById("timer"),
buttonElement = document.getElementById("myButton");
function myTimer(){
var current = new Date();
timerElement.innerHTML = current.toLocaleTimeString();
}
function toggle(){
if (startTimer) {
clearInterval(startTimer);
startTimer = null;
buttonElement.innerHTML = "Start";
} else {
buttonElement.innerHTML = "Stop";
startTimer = setInterval(myTimer, 1000);
}
}
<p id="timer"></p>
<button id="myButton" onclick="toggle()">Stop</button>
Why clearing your interval?
catch-up where the interval left.
var timer = document.getElementById("timer"),
paused = 0;
setInterval(function(){
if(!paused) timer.innerHTML = new Date().toLocaleTimeString();
}, 1000);
document.getElementById("myButton").addEventListener("click", function(){
this.innerHTML = (paused ^= 1) ? "Start" : "Stop";
});
<p id="timer"></p>
<button id="myButton">Stop</button>
P.S: Always cache elements you plan to reuse, specially if inside an interval fn.
(paused ^= 1) is used to toggle ones and zeroes 1,0,1,0,1... used than as boolean.

Log the time in between user - a simple timer

I'm trying to create a simple timer.
The user presses a 'start' button. When the user presses another button, I would like to log the time in between.
Could this be achieved with setTimeout?
setTimeout shouldn't be used for your situation. The following is a method to display the amount of seconds between clicking "startBtn" and then clicking "endBtn":
var date1 = new Date();
document.getElementById("startBtn").onclick = function(){
date1 = new Date();
}
document.getElementById("endBtn").onclick = function(){
var date2 = new Date();
var dif = date1.getTime() - date2.getTime();
var Seconds_from_T1_to_T2 = dif / 1000;
var Seconds_Between_Dates = Math.abs(Seconds_from_T1_to_T2);
alert(Seconds_Between_Dates);
}
You can build from here to get your desired functionality (for example, if the user clicks "endBtn" before clicking "startBtn", the results are inaccurate, of course. You can fix by disabling buttons as needed, etc.)
(thanks to How Many Seconds Between Two Dates?)
It's really not necessary to use a Timeout for this. All you want to do is measuring two difference between two time dates.
HTML:
<span class="startTimer">
Start Timer
</span>
<span class="stopTimer">
Stop Timer
</span>
<span class="result">
</span>
JS, and no, the use of JQuery is not needed here but I like the way it handles events:
(function($){
var Timer = {
startTimeInMs: null,
endTimeInMs: null,
start: function(){
this.startTimeInMs = new Date();
},
stop: function(){
this.endTimeInMs = new Date();
},
getTime: function(){
return this.endTimeInMs - this.startTimeInMs;
},
bind: function() {
var self = this;
$('.startTimer').on('click', function(){
self.start();
});
$('.stopTimer').on('click', function(){
self.stop();
self.printResult();
});
},
printResult: function() {
$(".result").html(this.getTime())
},
init: function(){
this.bind();
}
}
var timer = Object.create(Timer);
timer.init();
})(jQuery);
You can just use the Date.now() method, there's no need to instantiate a new Date object each time.
Here's a jsFiddle that measures lap times as an example: http://jsfiddle.net/ZpFnp/
HTML
<button id="start">start/reset</button>
<button id="stop">lap</button>
<div id="output"></div>
JavaScript
var startTime = Date.now();
document.getElementById("start").addEventListener("click", function () {
document.getElementById("output").innerHTML = "";
startTime = Date.now();
});
document.getElementById("stop").addEventListener("click", function () {
var elapsedTime = Date.now() - startTime;
document.getElementById("output").innerHTML += "<p>" + elapsedTime + "</p>";
});

Why does this javascript timer code work in Chrome debugger but not when run normally

The code below periodically updates a div element with new text. If I set a breakpoint in the Chrome debugger and run in step mode the code updates the html as I expected. But if run without any breakpoint set I see:
minutes = 0 seconds = 0
printed and then no change.
What am I doing wrong?
<html>
<script type="text/javascript">
var g_t1 = null;
var g_t2 = null;
function StartTimer() {
g_t1 = new Date();
}
function StopTimer() {
g_t2 = new Date();
}
function CalcDuration() {
StopTimer();
var diff = g_t2.getTime() - g_t1.getTime();
var place = document.getElementById("here");
var minutes = Math.floor((diff / 1000) / 60);
var seconds = Math.floor((diff / 1000) % 60);
place.innerHTML = "minutes = " + minutes + " seconds = " + seconds;
window.setTimeout(CalcDuration(), 100);
}
function Poller() {
if(!g_t1)
StartTimer();
window.setTimeout(CalcDuration(), 100);
}
</script>
<body onload="Poller();">
<div id="here"></div>
</body>
</html>
EDIT.
For anyone interested both these variants work:
window.setTimeout(CalcDuration, 100);
or
window.setTimeout(function(){CalcDuration()}, 100);
You need to wrap your timer function call in an anonymous function, otherwise it executes immediately instead of within the scope of the timer.
window.setTimeout(function(){CalcDuration()}, 100);
When setTimeout works in debug mode, but not in production, and you use the function reference syntax, e.g.
window.setTimeout(CalcDuration, 100);
then you should make sure that you are defining the function like this:
CalcDuraction = function() {
...
}
rather than
function CalcDuration() {
...
}

Debugging JavaScript Timing Events

I'm having a problem with this JavaScript script. I've tried a number of things to get it to work. The alerts in there at current are there for debugging purposes, and seem to be failing to occur.
Help please?
function checkTime(this_time){
var the_string = "checkTime("+this_time+")";
var now = ((new Date()).getTime());
if(parseInt(now) >= parseInt(this_time)){
document.write("TIMEUP!");
}
alert(now);
alert(this_time);
var t = setTimeout(the_string,300);
}
var the_time = (((new Date()).getTime())+19000);
var the_string = "checkTime("+the_time+")";
var t = setTimeout(the_string,300);
Thanks,
Will.
Seems like you're looking for a countdown?
See this fiddle. The code is simplified to:
var bench = 19000 + new Date().getTime(),
timer = setInterval(
function(){
checkTime(bench);
}
, 1000
);
function checkTime(this_time){
var check = new Date - this_time;
if(check>=0){
alert('time\'s up!');
clearInterval(timer);
}
}
You should use setTimeout with closures instead of strings.
var now = new Date().getTime();
setTimeout(function(){
//your Javascript code here
//"now" can be used here as a closure
}, 300);
Here is a safer and self-contained version. A document.write after load will clear the page completely
http://jsfiddle.net/mplungjan/Zt5k7/
window.onload=function() {
var timer = function (endTime) {
var end = new Date(endTime);
var tId;
this.checkTime=function(){
var now = new Date();
document.getElementById("msg").innerHTML=now.toLocaleString();
if (now.getTime()>=end.getTime()) {
document.getElementById("msg").innerHTML="TIME's UP!";
clearInterval(tId);
}
}
tId = setInterval(this.checkTime,300);
}(new Date().getTime()+5000);
}
or for a proper countdown http://jsfiddle.net/mplungjan/Zt5k7/1/
window.onload=function() {
var timer = function (endTime) {
var end = new Date(endTime);
var tId;
this.checkTime=function(){
var now = new Date();
document.getElementById("msg").innerHTML=now.toLocaleString();
var diff = end.getTime()-now.getTime()
if (diff >= 1) document.getElementById("msg").innerHTML=parseInt(diff/1000)+1;
else {
document.getElementById("msg").innerHTML="TIME's UP!";
clearInterval(tId);
}
}
tId = setInterval(this.checkTime,300);
}(new Date().getTime()+9000);
}
I suppose the code could be made more simple to work.
function checkTime(this_time){
var now = ((new Date()).getTime());
if((now - this_time) >= 0){
document.write("TIMEUP!");
window.clearInterval(timer);
}
}
var t_t = (((new Date()).getTime())+19000);
var timer = window.setInterval(function(){
checkTime(t_t); }
, 300);
Cheers!

Categories

Resources