Recursive clock call keeps ticking despite my efforts? - javascript

I have a clock that I want to keep ticking, except when I put "break" in to the "seconds" parameter. When I do put "break", the clock breaks for a second, then keeps ticking. I want to have it stop ticking, and I have no idea what the problem is. For the record, I call this function on page load, and then whenever the user clicks elements on the page. It gets screwy after they click something.
var seconds;
function countdown_clock(seconds) {
if (seconds != "break") {
countdown(seconds);
seconds = seconds;
}
}
function displaymessage() {
alert("Your Time Has Expired");
}
function countdown(seconds) {
if (seconds != "break") {
Time_Left = seconds;
format = 1;
if (Time_Left < 0)
Time_Left = 0;
switch (format) {
case 0:
//The simplest way to display the time left.
$("div#ClockCountdown").html(Time_Left + ' seconds');
break;
case 1:
//More detailed.
Next_time = Time_Left - 1;
minutes = Math.floor(Time_Left / 60);
Time_Left %= 60;
seconds = Time_Left;
mps = 's';
sps = 's';
earlyzero = '';
latezero = '';
//ps is short for plural suffix.
if (minutes == 1) mps = '';
if (seconds == 1) sps = '';
if (seconds < 10) earlyzero = '0';
// if(seconds == 10) latezero ='0';
// document.all.countdown.innerHTML = minutes + ' minute' + mps + ' and ';
// document.all.countdown.innerHTML += seconds + ' second' + sps;
innerHTML = minutes + ':';
innerHTML += earlyzero + seconds;
$("div#ClockCountdown").html(innerHTML + "nonbroken!");
break;
default:
$("div#ClockCountdown").html(Time_Left + ' seconds');
}
if (Next_time == 0) {
displaymessage();
window.location.href = "navigation.php?nav=video_timeout";
}
else {
setTimeout('countdown(' + Next_time + ');', 1000);
}
}
}

You also have to clear the timeout. Do something like this:
var timeout;
function countdown(seconds) {
if (seconds == "break") {
clearTimeout(timeout);
}
// other things
if( Next_time == 0) {
displaymessage();
window.location.href ="navigation.php?nav=video_timeout";
} else {
timeout = setTimeout('countdown(' + Next_time + ');', 1000);
}
}

Timeouts are one shots, they are cleared when the timeout function is called. You should set the next timeout only if seconds !== 'break' :
if (Next_time == 0) {
displaymessage();
window.location.href = "navigation.php?nav=video_timeout";
}
else if (seconds !== 'break') {
setTimeout('countdown(' + Next_time + ');', 1000);
}

Related

JS interval not incrementing timer

The button I am listening in on and span element I want to
increment my timer in.
<p class="text2">art</p><br />
<p class="clocktext">
<span id="artSession">
<?php displayTime("art"); ?>
</span>
</p><br />
<button id="artBtn"> record </button><br />
<script type="text/javascript" src="includes/jquery.js"></script>
<script type="text/javascript" src="includes/jsfunctions.js"></script>
Here is my js functions file im calling from
// Beginning of tracker functionality
// variables to begin with
var interval;
var hours = 0;
var minutes = 0;
var seconds = 0;
var displayHrs = 0;
var displayMins = 0;
var displaySecs = 0;
var end, start, totalTime;
var timerStatus = false;
function sessionTimer() {
seconds = seconds + 1;
if(seconds >= 60 ) {
minutes++;
seconds = 0;
} else if ( minutes >= 60 ) {
hours++;
minutes = 0;
}
// logic to add leading 0
if( seconds < 10 ) {
displaySecs = '0' + seconds;
} else {
displaySecs = seconds;
} if( minutes < 10 ) {
displayMins = '0' + minutes;
} else {
displayMins = minutes;
} if( hours < 10 ) {
displayHrs = '0' + hours;
} else {
displayHrs = hours;
}
recordTime = displayHrs + ':' + displayMins + ':' + displaySecs;
document.getElementById('artSession').innerHTML = recordTime;
} // end of custom timer function
function buttonListening(catBtnId, catBtn, catSession, catSessionId, catagory) {
$(catBtnId).click(function() {
if(timerStatus == false) {
interval = setInterval(sessionTimer(), 1000);
document.getElementById(catBtn).innerHTML = 'stop';
timerStatus = true;
start = new Date();
}
else if (timerStatus == true) {
clearInterval(interval);
document.getElementById(catBtn).innerHTML = 'record';
end = new Date();
totalTime = end.getTime() - start.getTime();
timerStatus = false;
// reset timer values
hours = 0;
minutes = 0;
seconds = 0;
displayHrs = 0;
displayMins = 0;
displaySecs = 0;
// logic to add leading 0
if( seconds < 10 ) {
displaySecs = '0' + seconds;
} else {
displaySecs = seconds;
} if( minutes < 10 ){
displayMins = '0' + minutes;
} else {
displayMins = minutes;
} if( hours < 10 ){
displayHrs = '0' + hours;
} else {
displayHrs = hours;
}
//display formatted time in div
recordTime = displayHrs + ':' + displayMins + ':' + displaySecs;
document.getElementById(catSession).innerHTML = recordTime;
//#sign required !!include full path
$(catSessionId).load( 'includes/submit_time.php', {
postTimeCat: catagory ,
postTotalTime: totalTime
});
}
});
} // end of custom function storing btn event ---------------------------------------
buttonListening("#artBtn","artBtn","artSession","#artSession","art");
}); // end of js
Not quite sure where I'm going wrong. It was all working earlier today... GAHHH this project forsure has empowered me to start using github. Hope one of you guys can help me :C spent like all day smashing face off keyboard to get this thing to work. pet project almost done!
timeInterval = setInterval(sessionTimer(), 1000);
don't need parentheses '()' when passing function name in setInterval()
timeInterval = setInterval(sessionTimer, 1000);
hope this saves someone 4hrs

pause countdown javascript jquery

http://jsfiddle.net/vvccvvcc/mu45bptk/
how do I pause the timer? I want it to stop when it gets to 5 seconds
I tried this as seen in the fiddle
else {
isWaiting = true;
seconds--;
if (seconds == 5) {
seconds=seconds;}
}
does not work
The timer is initialized by setInterval(GameTimer, 1000);
if (seconds == 5) {
clearInterval(countdownTimer);
} else {
seconds--;
}
You will need to clear the interval in order to stop calling the function. Alternatively if you don't want to clear the interval you can say
if (seconds > 5) {
seconds--;
}
The way you've written it, second is decreased regardless of the condition (since it's before the if statement) and therefore, second = second becomes irrelevant.
Is this what you are looking for?
Fiddle: http://jsfiddle.net/mu45bptk/2/
var isWaiting = false;
var isRunning = false;
var seconds = 10;
var countdownTimer;
var finalCountdown = false;
function GameTimer() {
if (isWaiting) {
return;
}
var minutes = Math.round((seconds - 30) / 60);
var remainingSeconds = seconds % 60;
if (remainingSeconds < 10) {
remainingSeconds = "0" + remainingSeconds;
}
document.getElementById('waiting_time').innerHTML = minutes + ":" + remainingSeconds;
if (seconds == 0) {
if (finalCountdown) {
clearInterval(countdownTimer);
} else {
finalCountdown = true;
}
} else {
if (seconds == 5) {
isWaiting = true;
} else {
seconds--;
}
}
}
countdownTimer = setInterval(GameTimer, 1000);
You need to set isWaiting only if seconds == 5 and then check isWaiting on every run of GameTimer()

getting error: Cannot set property 'innerHTML' of null

i keep getting error said: Cannot set property 'innerHTML' of null.
i try to change innerHTML ->innerText. still not working.
what am i missing here???
function countdown(minutes) {
var seconds = 60;
var mins = minutes
function tick() {
var counter = document.getElementById("timer");
var current_minutes = mins-1;
seconds--;
counter.innerHTML =
current_minutes.toString() + ":" + (seconds < 10 ? "0" : "") + String(seconds);
if( seconds > 0 ) {
setTimeout(tick, 1000);
} else {
if(mins > 1){
// countdown(mins-1); never reach “00″ issue solved:Contributed by
Victor Streithorst
setTimeout(function () { countdown(mins - 1); }, 1000);
}
}
}
tick();
}
countdown(3);
html
<div id="timer"></div>
You're calling countdown(), which calls tick(), which calls document.getElementById("timer"), before that element has even been parsed.
Try doing it like this:
<div id="timer"></div>
<script type="text/javascript">
function countdown(minutes) {
var seconds = 60;
var mins = minutes
function tick() {
var counter = document.getElementById("timer");
var current_minutes = mins-1
seconds--;
counter.innerHTML = current_minutes.toString() + ":" + (seconds < 10 ? "0" : "") + String(seconds);
if( seconds > 0 ) {
setTimeout(tick, 1000);
} else {
if(mins > 1) {
// countdown(mins-1);
setTimeout(function () { countdown(mins - 1); }, 1000);
}
}
}
tick();
}
countdown(3);
</script>
In this case, order matters. You want to make sure the document has encountered that element before accessing it via the DOM.

Reset countdown interval with clearInterval doesn't work

I don't know how to reset ongoing counter. I have two counters on my page. It seems it works properly, but when I want to set new value to counter2 when it is still counting down, I see in my div two counting times. New and old one.
var interval1;
var interval2;
function countdown(element, minutes, seconds, timer) {
var el = document.getElementById(element);
clearInterval(timer);
timer = setInterval(function() {
if(seconds == 0) {
if(minutes == 0) {
(el.innerHTML = "---");
clearInterval(timer);
return;
}
else {
minutes--;
seconds = 60;
}
}
if(minutes > 0) {
var minute_text = minutes + (minutes > 1 ? ' minutes' : ' minute');
}
else {
var minute_text = '';
}
var second_text = seconds > 1 ? '' : '';
el.innerHTML = minute_text + ' ' + seconds + ' ' + second_text + '';
seconds--;
}, 1000);
}
function setCounter1(mins) {
countdown('timeLeft', mins, 00, interval1);
}
function setCounter2(mins) {
countdown('timeLeft2', mins, 00, interval2);
}
If for example I have set counter2 for 10mins, and after a minute I call setCounter2(3), I see in my timeLeft2 div two counters.
How can I reset ongoing counter?
Thanks for your help!
Reassigning an argument variable inside a function does not modify the argument outside of the function. You can see a demonstration of that fact here : http://jsfiddle.net/t6z5324y/
var outsideVariable = 0;
console.log('start', outsideVariable);
function foo(insideVariable) {
console.log('before', insideVariable);
insideVariable = 1;
console.log('before', insideVariable);
}
foo(outsideVariable);
console.log('end', outsideVariable);
But you can pass an object as an argument, and modify a member of that object inside the function. The solution will then be:
var intervalHolder1 = {timer: null};
var intervalHolder2 = {timer: null};
function countdown(element, minutes, seconds, timerHolder) {
//stuff
clearInterval(timerHolder.timer);
timerHolder.timer = setInterval(function() {
//stuff
}, 1000);
}
function setCounter1(mins) {
countdown('timeLeft', mins, 00, intervalHolder1);
}
function setCounter2(mins) {
countdown('timeLeft2', mins, 00, intervalHolder2);
}
I would do it by defining an array of Interval outside (how many you need) and making your function pass the Index of the Interval rather then the interval itself.
var interval1;
var interval2;
var arrayInterval = [interval1, interval2];
function countdown(element, minutes, seconds, timerId) {
var el = document.getElementById(element);
clearInterval(arrayInterval[timerId]);
arrayInterval[timerId] = setInterval(function() {
if (seconds == 0) {
if (minutes == 0) {
(el.value = "---");
clearInterval(arrayInterval[timerId]);
return;
} else {
minutes--;
seconds = 60;
}
}
if (minutes > 0) {
var minute_text = minutes + (minutes > 1 ? ' minutes' : ' minute');
} else {
var minute_text = '';
}
var second_text = seconds > 1 ? '' : '';
el.value = minute_text + ' ' + seconds + ' ' + second_text + '';
seconds--;
}, 1000);
}
function setCounter1(mins) {
countdown('timeLeft', mins, 00, 0);
}
function setCounter2(mins) {
countdown('timeLeft2', mins, 00, 1);
}

How to change the appearance of time changing dynamically using javascript in following scenario?

I'm using PHP, JavaScript, jQuery, Smarty, etc. for my website. I'm displaying time on a HTML file in Hr. Min. Sec. format. Actually, the time displayed is of a running test. It's displayed in countdown fashion. The time counter reduces the time dynamically(second by second) and ultimately reaches to zero(00:00:00). In short, the function is called recursively. The code for it as follows:
HTML
<body onLoad="load_timer('{$test_duration.hr}', '{$test_duration.min}', '{$test_duration.sec}', {$test_id}, '{$test_type}', '', '{$site_url});>
<div id="test_time_left">Time Left :<b><span id="time_value" style="padding-left:5px;"></span> </b> </div>
</body>
N.B.: If you are not getting the parameters I'm passing to load_timer function, please ignore the syntax of smarty and consider all the parameters as normal parameters.
JavaScript
var hrs;
var mins
var secs;
function cd(hr, mi, se, test_id, test_type, test_pack_id, path) {
hrs = 1 * h(hr);
mins = 1 * m(mi); // change minutes here
secs = 0 + s(se); // change seconds here (always add an additional second to your total)
redo(path, test_id, test_type, test_pack_id);
}
function h(obj) {
for(var i = 0; i < obj.length; i++) {
if(obj.substring(i, i + 1) == ":")
break;
}
return(obj.substring(0, i));
}
function m(obj) {
for(var i = 0; i < obj.length; i++) {
if(obj.substring(i, i + 1) == ":")
break;
}
return(obj.substring(0, i));
}
function s(obj) {
for(var i = 0; i < obj.length; i++) {
if(obj.substring(i, i + 1) == ":")
break;
}
return(obj.substring(0, i));
}
function display_time(hrs, mins, secs) {
var disp;
if(hrs <=9 ) {
disp = " 0";
} else {
disp = " ";
}
disp += hrs + " : ";
if(mins <= 9) {
disp += " 0";
} else {
disp += " ";
}
disp += mins + " : ";
if(secs <= 9) {
disp += "0" + secs;
} else {
disp += secs;
}
return(disp);
}
function redo(path, test_id, test_type, test_pack_id) {
secs--;
if(secs == -1) {
secs = 59;
mins--;
if(mins == -1) {
mins = 59;
hrs--;
}
}
document.getElementById('time_value').innerHTML = display_time(hrs, mins, secs); // setup additional displays here.
if((hrs == 0) && (mins == 0) && (secs == 0)) {
if(test_type=='public_test')
window.location = path
else
window.location = path+""+test_id+"/"+test_type+"/"+test_pack_id // redirects to specified page once timer ends and ok button is pressed
} else {
cd = setTimeout("redo('"+path+"', "+test_id +", '"+test_type+"', '"+test_pack_id+"')", 1000);
}
}
function load_timer(hr, mins, secs, test_id, test_type, test_pack_id, path) {
cd(hr, mins, secs, test_id, test_type, test_pack_id, path);
}
Till here everything is functioning perfectly. The issue I'm having is with the appearance of time I'm displaying.
Actually I want to display the time in values (in Hr: Min: Sec: values) in red color when the remaining time is five minutes i.e. (from 00:05:59). Also the timer should get blink till it reaches zero (i.e. 00:00:00). How should I do this?
I'm not sure if I understood your question right ...
Take a look at this jsFiddle http://jsfiddle.net/QLa8b/
I added 2 few lines, so that the minutes are displayed in red when they are lower or equal 5:
if(hrs == 0 && mins <= 5) disp += '<span style="color: red">';
...
if(hrs == 0 && mins <= 5) disp += '</span>';
You can do this with the other time values as well. I also added a blinking colon, but I think that's what you wanted to blink?

Categories