Timer doesnt end when it reaches zero - javascript

I have been working on this javascript timer and can't understand why it doesnt stop when the hours, minutes and seconds are equal to zero.
Code:
var s= 18000;
var h= Math.floor(s/3600);
s-= h*3600;
var m= Math.floor(s/60);
s -= m*60;
var counter=setInterval(timer, 1000); //1000 will run it every 1 second
function timer()
{
if(s == 0 ){
if(m == 0){
h=h-1;
s=59;
m=59;
if(h == 0){
clearInterval(counter);
}
} else {
m=m-1;
s=59;
}
//Do code for showing the number of seconds here
} else {
s = s - 1;
}
document.getElementById("timer").innerHTML=h+'hrs '+m+'min '+s+'secs ';
}

The problem I see here is that you'll decrement h variable by 1 when all time variables - and by time variables I mean h, m and s are set to zero:
if(s == 0 ) {
if(m == 0) {
h=h-1;
s=59;
m=59;
// more code goes here
So h will be -1 and the timer will never stop.
The best I can propose is to rewrite your timer completely, and use only seconds here. Every time the timer function gets invoked you check if s equals to zero - if it is, you stop the timer. Otherwise, you decrement s by 1. To update the inner HTML of #timer element you can recalculate the number of hours, minutes and seconds on the every invocation of timer method - this solution will be a lot more easier to understand and maintain than the chain of nested conditional statements.

The problem appears to be the logic in this section here...
if(s == 0 ){
if(m == 0){
h=h-1; // what if h is also 0 here?? this would set it negative
s=59;
m=59;
if(h == 0){
clearInterval(counter);
}
I think you should be doing your if(h==0) check sooner... before you decrement the values. So you might want to start your if else block with a if (s == 0 && m == 00 && h == 0) and use that to clear the interval. If everything is already zero, you don't want to change any more values.

Related

How can I execute code when a HTML element (total number of orders remaining) reaches "0"?

I have a 1 second interval set, which essentially checks whether the total orders has reached zero each time the interval passes. The trouble with this is that the code within the if statement continues to run each second once the condition is met.
if (theHours >= 16 && theHours < 17) {
function ordersComplete() {
let totalRemaining = document.getElementById("total-remaining");
if (totalRemaining.textContent == 0) {
console.log("nice swan");
}
};
setInterval(ordersComplete, 1000);
}
If you want to decide dynamically whether another invocation of the function is necessary, I suggest to replace the use of setInterval with setTimeout. This can be used for a recursive delayed invocation:
function ordersComplete() {
let totalRemaining = document.getElementById("total-remaining");
if (totalRemaining.textContent == 0) {
console.log("nice swan");
} else {
setTimeout(ordersComplete, 1000);
};
}
if (theHours >= 16 && theHours < 17) {
ordersComplete();
}
Use clearInterval() when you want to stop the timer.
if (theHours >= 16 && theHours < 17) {
let interval = setInterval(ordersComplete, 1000);
function ordersComplete() {
let totalRemaining = document.getElementById("total-remaining");
if (totalRemaining.textContent == 0) {
console.log("nice swan");
} else {
clearInterval(interval);
}
};
}
You've declared your function inside of your if statement, which is causing your problem.
You'll instead want to declare your function separately, and then call it when you're supposed to.
function ordersComplete(){
let totalRemaining = document.getElementById("total-remaining");
if (totalRemaining.textContent == 0) {
console.log("nice swan");
}
};
if(theHours >= 16 && theHours < 17){
setInterval(ordersComplete, 1000);
}

How do I set "display:none" after 5 seconds to the div i previously set "display:initial" in JavaScript?

I'm trying to create a greeting pop-up and make it appear for only 5 secs, but I don't really get how to make it work.
Thanks in advance!
Here's code:
function greeting(event){
if (time >= 6 && time <= 11 ){
goodMorning.style = 'display:initial'
} else if (time >= 13 && time <= 17){
goodDay.style = 'display:initial'
} else if (time >= 17 && time <= 22) {
goodEvening.style = 'display:initial'
} else {
welcome.style = 'display:initial'
}
};
No need for all that complicated work. Just use a setTimeout to execute a function after a specified number of miliseconds.
var goodEvening = document.getElementById("a");
setTimeout(function(){hide(goodEvening);}, 5000);
function hide(element){
element.style.display="none";
}
<p id="a">Good evening!</p>
jQuery approach:
setTimeout(function(){$('#a').hide();},5000);
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<p id="a">Good evening!</p>

checking the time with Date.getSeconds() is not working

I'm using JavaScript to check the user's time every 600ms (so my code runs once a second, but the time is unlikely to shift due to deviation in the setInterval method). My code looks like this:
setCorrectingInterval(function(){
needs_run = false;
switch(date.getDay()) {
case 1:
if(date.getHours() == "8" && date.getMinutes() == "50" && date.getSeconds() == "0") {
next = array.ItemA;
needs_run = true;
}
break;
[abridged, all other ifs and cases are identical except the times and days]
}
if(needs_run == true) {
alert("foobar");
}
}
(setCorrectingInterval is a custom function designed to correct the deviation from setInterval as much as possible)
My issue is that I never get alert("foobar"). I've used console.log() and done some trial-and-error, what I've narrowed it down to is the date.getSeconds() == 0 call. I've tried using (date.getSeconds() <= "5" && date.getSeconds() >= "0"), to no avail. The desired outcome is that, in this case, at 8:50AM on Monday, I get an alert, once.
When I omit the date.getSeconds() call, it works fine and dandy.
My guess is that something with your setCorrectingInterval() function or the date variable is wrong. It works fine with new Date().
;window.setInterval(function(){
var tDate = new Date()
console.log(tDate.getDay(), tDate.getHours(), tDate.getMinutes(), tDate.getSeconds())
needs_run = false;
switch(tDate.getDay()){
case 1:
if(tDate.getHours() == "8" && tDate.getMinutes() == "50" && tDate.getSeconds() == "0"){
//next = array.ItemA;
needs_run = true;
}
break;
case 5:
//No need to compare to string
//if(date.getHours() == "13" && date.getMinutes() >= "50" && date.getSeconds() >= "0") {
if(tDate.getHours() == 13 && tDate.getMinutes() >= 50 && tDate.getSeconds() >= 0){
//next = array.ItemA;
needs_run = true;
}
break;
}
if(needs_run == true){
console.log('foorbar') //alerts can be bad.
}
}, 1000);
More than likely, date is not what you expect it to be. I suppose the following would be more appropriate for your case:
var date = new Date();
switch(date.getDay()) {
...
You commented:
setCorrectingInterval is a custom function designed to correct the
deviation from setInterval as much as possible
What does that even mean? What do you mean by "correct the deviation from setInterval"?

How do I reset the count when a condition is met?

I'm trying to reset the count to 0 when conditions 1 or 2 are met when looping through one function every 2 seconds. At what point would I implement the reset. For example;
var timer;
var a = 'door';
var b = '';//this is set by an ajax call that fires off every second
var count = 0;
function condition(){
//condition 1
if(a == 'door' && b == 'inside' && count < 30){
$('#action').html('Person A');
count++;
//after 1 minute show 1 minute sign
} else {
$('#action').html('It\'s been 1 minute');
count = 31;
}
//condition 2
if(a == 'door' && b == 'outside' && count < 30){
$('#action').html('Person B');
count++;
//after 1 minute show 1 minute sign
} else {
$('#action').html('It\'s been 1 minute');
count = 31;
}
//condition 3
//empty div & reset count
if(b == ''){
$('#action').empty();
count = 0;
}
//set interval
clearInterval(timer);
timer = setInterval(condition, 2000);// 2 seconds x 30 = 1 minute
}
condition();
There's something off with your code, specifically for the setInterval function. The first parameter should be a function object, NOT the invokation of a function:
Should be this:
setInterval( condition, 2000 );

Stuck creating a php/javascript countdown timer

I have been struggling to get my head around this for a while now.
I am attempting to create a countdown timer. Eventually I want it to reset after every 5 hours starting from 8am. But for now I can't figure out if im setting the hours, minutes and seconds correctly to count down together properly.
This is my code so far:
<?php
$timeTo = strtotime('08:00:00').'<br />';
$timeNow = strtotime('now').'<br />';
$differenceInSeconds = $timeTo - $timeNow;
?>
<script type="text/javascript">
var s= "<?php Print($differenceInSeconds);?>";
var h= Math.floor(s/3600);
s-= h*3600;
var m= Math.floor(s/60);
s -= m*60;
var counter=setInterval(timer, 1000); //1000 will run it every 1 second
function timer()
{
s=s-1;
if(h >= 0 && m >= 0 && s <= -1){
m=m-1;
s=59;
if(h>= 0 && m < 0 && s <= -1){
h=h-1;
m=59;
s=59;
if (s <= -1)
{
//counter ended, reset counter
return;
}
}
}
//Do code for showing the number of seconds here
document.getElementById("timer").innerHTML=(h <= 0 ? ' ' : h+"hr ")+(m <= 0 ? ' ' : m+"min ")+(s < 10 ? '0'+s : s+"secs "); // watch for spelling
}
</script>
Am I barking up the wrong tree here? I am new to times and javascript so finding it difficult.
I will not answer this. I will just try to lead you to the answer.
Note that s <= -1 is logically equivalent to s < 0. There is no confusion about it. Use the second one, it looks more clean.
s=59; and in the next line how on earth will if(h>= 0 && m < 0 && s <= -1 ) ever evaluate to true ?
Similar other logical mistakes are present as well. Take some time and fix this. If you fix this on your own then you're one step closer to becoming a good programmer.
Happy Coding... :)

Categories

Resources