Reset countdown interval with clearInterval doesn't work - javascript

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);
}

Related

JQuery - How to update variable after call function?

I have a timer function, I want to change the value of my variable after the timer reaches 0?
function countdown(minutes) {
var seconds = 60;
var mins = minutes
function tick() {
var counter = document.getElementById("timer");
current_minutes = mins - 1
seconds--;
counter.innerHTML =
current_minutes.toString() + ":" + (seconds < 10 ? "0" : "") + String(seconds);
if (parseInt(current_minutes) === 0 && parseInt(seconds) === 00) {
sendAgain.show();
finalMin = parseInt(current_minutes);
finalSec = parseInt(seconds);
}
if (seconds > 0) {
timeoutHandle = 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();
}
variables :
let finalMin = null;
var finalSec = null;
I want the variables to be set after the following code is executed?
if (parseInt(current_minutes) === 0 && parseInt(seconds) === 00) {
sendAgain.show();
finalMin = parseInt(current_minutes);
finalSec = parseInt(seconds);
}
countdown(2);
console.log(finalMin); ===== show "0"

Reset multiple timers in JS

I try to create a website with multiple timers. I used a script from a website.
But in this script is it not possible to reset one timer or both timers.
I want to start timer1 again from the beginning, so I have to reset the timer first.
How can I reset the timer/s to start it with a new value??
In the end, I want to start Timer1, after that start Timer2 with the remaining time from Timer1 + the new time of Timer2.
function countdown(element, minutes, seconds) {
// Fetch the display element
var el = document.getElementById(element);
// Set the timer
var interval = setInterval(function() {
if (seconds == 0) {
if (minutes == 0) {
(el.innerHTML = "STOP!");
clearInterval(interval);
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);
}
//Start as many timers as you want
var start1 = document.getElementById('timer1');
var start2 = document.getElementById('timer2');
start1.onclick = function() {
countdown('countdown1', 0, 15);
}
start2.onclick = function() {
countdown('countdown2', 0, 10);
}
<html>
<head>
</head>
<body>
<div id='countdown1'></div>
<div id='countdown2'></div>
<input id="timer1" type="button" value="Start timer 1" />
<input id="timer2" type="button" value="Start timer 2" />
</body>
</html>
Thanks for your help
You can bind the interval as a property to the element itself.
if ( el.interval )
{
clearInterval( el.interval );
}
// Set the timer
var interval = el.interval = setInterval(function() {
Demo
function countdown(element, minutes, seconds) {
// Fetch the display element
var el = document.getElementById(element);
if ( el.interval )
{
clearInterval( el.interval );
}
// Set the timer
var interval = el.interval = setInterval(function() {
if (seconds == 0) {
if (minutes == 0) {
(el.innerHTML = "STOP!");
clearInterval(interval);
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);
}
//Start as many timers as you want
var start1 = document.getElementById('timer1');
var start2 = document.getElementById('timer2');
start1.onclick = function() {
countdown('countdown1', 0, 15);
}
start2.onclick = function() {
countdown('countdown2', 0, 10);
}
<html>
<head>
</head>
<body>
<div id='countdown1'></div>
<div id='countdown2'></div>
<input id="timer1" type="button" value="Start timer 1" />
<input id="timer2" type="button" value="Start timer 2" />
</body>
</html>
You need a return and store a reference to your variable that holds the interval (interval) you can then call clearinterval on the handle:
The relevant changes are:
//variables to hold the intervals
var countdown1Interval;
var countdown2Interval;
start1.onclick = function() {
countdown1Interval = countdown('countdown1', 0, 15);
}
start2.onclick = function() {
countdown2Interval = countdown('countdown2', 0, 10);
}
//event to reset
resetBoth.onclick = function(){
//null check because the button might not of been pressed
if (countdown1Interval){
clearInterval(countdown1Interval);
countdown1Interval = undefined;
}
if (countdown2Interval){
clearInterval(countdown2Interval);
countdown2Interval = undefined;
}
}
You also need to return the interval handle in countdown (return interval;)
Full snippet
function countdown(element, minutes, seconds) {
// Fetch the display element
var el = document.getElementById(element);
// Set the timer
var interval = setInterval(function() {
if (seconds == 0) {
if (minutes == 0) {
(el.innerHTML = "STOP!");
clearInterval(interval);
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);
return interval;
}
//Start as many timers as you want
var start1 = document.getElementById('timer1');
var start2 = document.getElementById('timer2');
var resetBoth = document.getElementById('resetBoth');
var countdown1Interval;
var countdown2Interval;
start1.onclick = function() {
countdown1Interval = countdown('countdown1', 0, 15);
}
start2.onclick = function() {
countdown2Interval = countdown('countdown2', 0, 10);
}
resetBoth.onclick = function(){
if (countdown1Interval){
clearInterval(countdown1Interval);
countdown1Interval = undefined;
}
if (countdown2Interval){
clearInterval(countdown2Interval);
countdown2Interval = undefined;
}
}
<html>
<head>
</head>
<body>
<div id='countdown1'></div>
<div id='countdown2'></div>
<input id="timer1" type="button" value="Start timer 1" />
<input id="timer2" type="button" value="Start timer 2" />
<input id="resetBoth" type="button" value="Stop both timers" />
</body>
</html>

Javascript function inside called in loop

Good day,
I found a sweet little javascript that suits my needs but I want to call this function many times on the same page. It is my understanding that for each call to the function needs to be defined with a unique id.
I would put this in a loop like this end like this
<td><div id='countdown$i'></div></td>
Here is the loop
$i=0;
if( mysqli_num_rows($result) > 0){
if ($time < $endtime) {
echo "<script>
var interval;
var minutes = 1;
var seconds = 10;
window.onload = function() {
countdown('countdown');
}
function countdown(element) {
interval = setInterval(function() {
var el = document.getElementById(element);
if(seconds == 0) {
if(minutes == 0) {
location.reload(true);
} else {
minutes--;
seconds = 60;
}
}
if(minutes > 0) {
var minute_text = minutes + (minutes > 1 ? ' min(s)' : ' min');
var secound_text = '';
el.innerHTML = 'Ready in ' + minute_text;
} else {
var minute_text = '';
var second_text = seconds + (seconds > 1 ? ' sec(s)' : ' sec');
el.innerHTML = 'Ready in ' + second_text;
}
seconds--;
}, 1000);
}
</script>";
echo "<td width='200'><div id='countdown$i'></div></td>";
$i++;
}
What/where should i modify the script to repond to countdown$i ?
Thanks
Not sure why you are doing it this way; however, this should fix your code.
window.onload = function() {
countdown('countdown".$i."');
}

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.

Recursive clock call keeps ticking despite my efforts?

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);
}

Categories