Countdown with a delay in JavaScript - javascript

I've started to learn JavaScript, and I'm coding a program that get a number from the user and counts down to zero with a delay of one second for each number.
This is my code:
function DescreasNo(){
var MyInput = parseInt(document.getElementById('HoursOfWork').value);
var output = document.getElementById('output01');
output.innerHTML = '';
for ( var i=MyInput ; i>0 ; i--){
output.innerHTML += i +"<br>";
}
}
<!DOCTYPE html>
<html lang="en" xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta charset="utf-8" />
<link rel="stylesheet" href="StyleSheet.css" />
<script src="Script.js"></script>
<title>EyeProctect Project</title>
</head>
<body>
<h1>Eye Protect</h1>
<h4>Keep Your Eyes safe</h4>
<input type="text" id="HoursOfWork" placeholder="Enter your hours of work ...." />
<button class="start" onclick="DescreasNo()" >Let's Go!</button>
<p id="output01"></p>
</body>
</html>
I used setTimeout and setInterval, but my problem is that it just shows zeros for each number, like this:
0, 0, 0, 0
Please help me to solve this problem.

You can use setTimeout() with IIFE:
function DescreasNo(){
var MyInput = parseInt(document.getElementById('HoursOfWork').value);
var output = document.getElementById('output01');
output.innerHTML = '';
(function loop (i) {
setTimeout(function () {
output.innerHTML += i +"<br>";
if (--i) loop(i); // call the function until end
}, 1000); // 1 second delay
})(MyInput);
}
<h1>Eye Protect</h1>
<h4>Keep Your Eyes safe</h4>
<input type="text" id="HoursOfWork" placeholder="Enter your hours of work ...." />
<button class="start" onclick="DescreasNo()" >Let's Go!</button>
<p id="output01"></p>

You're probably misunderstanding how to user a closure along with setTimeout (or setInterval).
function decreaseNumber() {
const total_hours = parseInt(document.getElementById('HoursOfWork').value);
const output_div = document.getElementById('output01');
let current_hour = total_hours;
const countdown = () => {
output_div.innerHTML += current_hour + "<br />";
if (--current_hour > 0) {
setTimeout(countdown, 1000); // 1000 milliseconds
}
};
countdown();
}
<!doctype html>
<html>
<head>
<meta charset="utf-8" />
<link rel="stylesheet" href="StyleSheet.css" />
<script src="Script.js"></script>
<title>EyeProctect Project</title>
</head>
<body>
<h1>Eye Protect</h1>
<h4>Keep Your Eyes safe</h4>
<input id="HoursOfWork" placeholder="Enter your hours of work ...." />
<button class="start" onclick="decreaseNumber()">Let's Go!</button>
<p id="output01"></p>
</body>
</html>

With setInterval you could do it like this.
function DescreasNo(){
var MyInput = parseInt(document.getElementById('HoursOfWork').value);
var output = document.getElementById('output01');
output.innerHTML = '';
var countDown = MyInput;
var intervalId = setInterval(function () {
output.innerHTML += countDown +"<br>";
if (--countDown <= 0)
clearInterval(intervalId); // clear timer when finished
}, 1000); // 1 second delay between decrements
}
<h1>Eye Protect</h1>
<h4>Keep Your Eyes safe</h4>
<input type="text" id="HoursOfWork" placeholder="Enter your hours of work ...." />
<button class="start" onclick="DescreasNo()" >Let's Go!</button>
<p id="output01"></p>

I would do this with a setInterval you can allow fractional hours if you use parseFloat instead of parseInt. You can also format the seconds fairly easily to give a nice readout.
You should be careful about clearing the interval too incase someone presses the button more than once during the countdown otherwise you will get multiple timers. Here if you press twice it resets it.
Some improvements would include validating input to make sure it's a number:
let int;
function DescreasNo() {
clearInterval(int) // clear interval to allow button to reset counter
var MyInput = document.getElementById('HoursOfWork').value;
let seconds = (parseFloat(MyInput) * 60 * 60)
var output = document.getElementById('output01');
int = setInterval(() => {
if (seconds <= 0) { // finished
clearInterval(int)
return
}
output.innerHTML = formatTime(seconds--)
}, 1000)
}
function formatTime(seconds) {
let hours = Math.floor(seconds / (60 * 60)).toString().padStart(2, '0')
let minutes = Math.floor((seconds - hours * 3600) / 60).toString().padStart(2, '0');
let second = Math.floor(seconds - (hours * 3600) - (minutes * 60)).toString().padStart(2, '0');
return `${hours}:${minutes}:${second}`;
}
<h1>Eye Protect</h1>
<h4>Keep Your Eyes safe</h4>
<input type="text" id="HoursOfWork" placeholder="Enter your hours of work ...." />
<button class="start" onclick="DescreasNo()">Let's Go!</button>
<p id="output01"></p>

Related

Stopwatch Timer is slower than normal time

I want to make a stopwatch in JavaScript that could count milliseconds, seconds, minutes, and hours. The problem is that it seems to not go at the proper speed, meaning that when I compare it to other timers, it gradually becomes slower than them (i.e the speed at which the timer is counting slows down over time). So suddenly, there are 5-second differences, then it becomes 7-second differences, and so on. Any help would be appreciated.
My code for Stopwatch.
var hr = 0;
var min = 0;
var sec = 0;
var count = 0;
var Startbutton = document.getElementById("Start");
var timer = false;
function start() {
Startbutton.disabled = true; //this wil help to avoid multiple clicking on function
timer = true;
stopwatch();
}
function stop() {
timer = false;
Startbutton.disabled = false;
}
function reset() {
timer = false;
Startbutton.disabled = false;
min = 0;
hr = 0;
sec = 0;
count = 0;
document.getElementById("hr").innerHTML = "00";
document.getElementById("min").innerHTML = "00";
document.getElementById("sec").innerHTML = "00";
document.getElementById("count").innerHTML = "00";
}
function stopwatch() {
if (timer) {
++count;
if (count > 99) {
++sec;
count = 0;
}
if (sec > 59) {
min++;
sec = 0;
}
if (min > 59) {
hr++;
min = 0;
sec = 0;
}
if (hr > 23) {
hr = 0;
sec = 0;
min = 0;
}
var hrString = hr;
var minString = min;
var secString = sec;
var countString = count;
if (hr < 10) {
hrString = "0" + hrString;
}
if (min < 10) {
minString = "0" + minString;
}
if (sec < 10) {
secString = "0" + secString;
}
if (count < 10) {
countString = "0" + countString;
}
document.getElementById("hr").innerHTML = hrString;
document.getElementById("min").innerHTML = minString;
document.getElementById("sec").innerHTML = secString;
document.getElementById("count").innerHTML = countString;
console.log("hello");
setTimeout(stopwatch, 10);
}
}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Stopwatch</title>
<link rel="stylesheet" href="style.css" />
</head>
<body>
<div id="container">
<div id="time">
<span class="digit" id="hr">00</span>
<span class="txt">Hr</span>
<span class="digit" id="min">00</span>
<span class="txt">Min</span>
<span class="digit" id="sec">00</span>
<span class="txt">Sec</span>
<span class="digit" id="count">00</span>
</div>
<div id="btn-container">
<button class="btn" id="Start" onclick="start()">Start</button>
<button class="btn" id="Stop" onclick="stop()">Stop</button>
<button class="btn" id="Reset" onclick="reset()">Reset</button>
</div>
</div>
<script src="script.js"></script>
</body>
</html>
Because you don't take into account the time it takes for it to draw the html. Need to re-design to use system clock. See my example.
var hr = 0;
var min = 0;
var sec = 0;
var count = 0;
var Startbutton = document.getElementById("Start");
var timer = false;
var start_time;
function start() {
Startbutton.disabled = true; //this wil help to avoid multiple clicking on function
timer = true;
start_time = (new Date()).getTime();
stopwatch();
}
function stop() {
timer = false;
start_time = null;
Startbutton.disabled = false;
}
function reset() {
timer = false;
start_time = null;
Startbutton.disabled = false;
min = 0;
hr = 0;
sec = 0;
count = 0;
document.getElementById("hr").innerHTML = "00";
document.getElementById("min").innerHTML = "00";
document.getElementById("sec").innerHTML = "00";
document.getElementById("count").innerHTML = "00";
}
function stopwatch() {
var now = (new Date()).getTime();
var diff = now - start_time;
if (timer) {
var str_time = (new Date(diff).toISOString().slice(11, 23)); // 👉️ 15:00:00.000
var hrString = ""+str_time.substring(0,2);
var minString = ""+str_time.substring(3,5);
var secString = ""+str_time.substring(6,8);
var countString =""+ str_time.substring(9,11);
document.getElementById("hr").innerHTML = hrString;
document.getElementById("min").innerHTML = minString;
document.getElementById("sec").innerHTML = secString;
document.getElementById("count").innerHTML = countString;
//console.log("hello");
requestAnimationFrame(stopwatch)
}
}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Stopwatch</title>
<link rel="stylesheet" href="style.css" />
</head>
<body>
<div id="container">
<div id="time">
<span class="digit" id="hr">00</span>
<span class="txt">Hr</span>
<span class="digit" id="min">00</span>
<span class="txt">Min</span>
<span class="digit" id="sec">00</span>
<span class="txt">Sec</span>
<span class="digit" id="count">00</span>
</div>
<div id="btn-container">
<button class="btn" id="Start" onclick="start()">Start</button>
<button class="btn" id="Stop" onclick="stop()">Stop</button>
<button class="btn" id="Reset" onclick="reset()">Reset</button>
</div>
</div>
<script src="script.js"></script>
</body>
</html>
You should take time from system clock. Otherwise time will be relative in your code :)
The code below you can inspect.
var hr = 0;
var min = 0;
var sec = 0;
var count = 0;
var Startbutton = document.getElementById("Start");
var startTime = Date.now();
var timer = false;
function start() {
Startbutton.disabled = true; //this wil help to avoid multiple clicking on function
timer = true;
startTime = Date.now();
stopwatch();
}
function stop() {
timer = false;
Startbutton.disabled = false;
}
function reset() {
timer = false;
Startbutton.disabled = false;
min = 0;
hr = 0;
sec = 0;
count = 0;
document.getElementById("hr").innerHTML = "00";
document.getElementById("min").innerHTML = "00";
document.getElementById("sec").innerHTML = "00";
document.getElementById("count").innerHTML = "00";
}
function stopwatch() {
if (timer) {
var elapsedTime = Date.now() - startTime;
var hr = Math.floor(elapsedTime / (60 * 60 * 1000) % 24).toString().padStart(2, '0');
var min = Math.floor(elapsedTime / (60 * 1000) % 60).toString().padStart(2, '0');
var sec = Math.floor(elapsedTime / 1000 % 60).toString().padStart(2, '0');
var msec = Math.floor(elapsedTime % 1000).toString().padStart(2, '0');
document.getElementById("hr").innerHTML = hr;
document.getElementById("min").innerHTML = min;
document.getElementById("sec").innerHTML = sec;
document.getElementById("count").innerHTML = msec;
setTimeout(stopwatch, 10);
}
}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Stopwatch</title>
<link rel="stylesheet" href="style.css" />
</head>
<body>
<div id="container">
<div id="time">
<span class="digit" id="hr">00</span>
<span class="txt">Hr</span>
<span class="digit" id="min">00</span>
<span class="txt">Min</span>
<span class="digit" id="sec">00</span>
<span class="txt">Sec</span>
<span class="digit" id="count">00</span>
</div>
<div id="btn-container">
<button class="btn" id="Start" onclick="start()">Start</button>
<button class="btn" id="Stop" onclick="stop()">Stop</button>
<button class="btn" id="Reset" onclick="reset()">Reset</button>
</div>
</div>
<script src="script.js"></script>
</body>
</html>

i can't get the value from an input

i'm making a basic timer, is one of my first projects, when you press a button the code should create 3 different variables that obtain the values from their respective inputs, this 3 symbolize hours, minutes and seconds.
what happens is that if you console.log any of this 3 variables you get that is undefined for some reason, if you don't have this values the entire countdown will not work.
the inputs are set to start at value = 0 in the html, so it's supposed to at least return 0, not undefined
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<link rel="stylesheet" href="styles.css">
</head>
<body>
<div class="title-container">
<div class="title"><h1>vamos a meditar un poco...</h1> </div>
</div>
<div class="timer-container">
<div class="screen-timer"><h2></h2></div>
<input type="number" min="0" max="60" value="0" id="hours">
<input type="number" min="0" max="60" value="0" id="minutes">
<input type="number" min="0" max="60" value="0" id="seconds">
</div>
<div class="button-container">
<button class="btn">Iniciar</button>
</div>
<script src="app.js"></script>
here is the javascript code:
let button = document.querySelector(".btn");
let title = document.querySelector(".title");
let screenTimer = document.querySelector(".screen-timer");
//quotes
let quotes = ["OM MANI PADME HUM", "OM", "BUENOS PENSAMIENTOS, BUENAS PALABRAS, BUENAS ACCIONES", "YO FLUYO COMO EL AGUA"];
//timer start button
button.addEventListener("click", function(){
//time units
let h = document.getElementById("hours").value;
let m = document.getElementById("minutes").value;
let s = document.getElementById("seconds").value;
//title changer
let index = parseInt((Math.random() * quotes.length));
title.innerHTML = `<div class="title"><h1>${quotes[index]}</h1></div>`;
//interval for the timer
let intervalId = setInterval(timer, 1000);
//timer
function timer(){
if(m > 0 && s <= 59){
s--;
} else if(m > 0 && s == 0){
m--;
s = 59;
} else if (h > 0 && m == 0 && s == 0){
h--;
m = 59;
s = 59;
}
if (h === 0 && m === 0 && s === 0){
clearInterval(intervalId)
}
}
//show the timer on the screen
screenTimer.innerHTML = `<div class="screen-timer"><h2> ${h + ":" + m + ":" + s} </h2></div>`
console.log(h);
console.log(m);
console.log(s);
console.log(h.value);
console.log(m.value);
console.log(s.value);
});
i saw other solutions where people write document.getElementById(id).onClick instead of using addEventListener("click", ...) for making the button work when its clicked on, but i think it's the same
You are accessing the values for hours, minutes, and seconds correctly here,
let h = document.getElementById("hours").value;
let m = document.getElementById("minutes").value;
let s = document.getElementById("seconds").value;
And they are giving correct results in your console logs as well,
console.log(h);
console.log(m);
console.log(s);
What you are doing wrong is then trying to access the .value property of these three variables which doesn't exist and that is why undefined is getting printed.
Use h, m, s variables for your output.
The first three console.logs yield the correct results.
console.log(h);
console.log(m);
console.log(s);
These are already the values themselves not the domnodes.
console.log(h.value);
console.log(m.value);
console.log(s.value);
When you try to access the property "value" on the values themselves the result is undefined.

Create a countdown timer on button click when value is entered in text box : Javascript

I meet a problem like when I try to enter a number like 30, and count it down until 0, but it doesn't work.
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<title>123</title>
<script type="text/javascript">
function startTimer()
{
seconds = seconds - 1;
if (seconds <= 0)
{
seconds = 0;
}
else
{
seconds--;
}
var obj = document.getElementById("timer");
obj.display.value= seconds;
}
</script>
</head>
<body>
<form id="timer" action="#">
<p><input type="text" name="display" size="
20" /></p>
<p><input type="button" value="Start"
onclick="Id=setInterval('startTimer()', 100)" />
</form>
</script>
</body>
</html>
I think the problem is in if else statement, I am not sure if I make the user input correct.
Just assign 'seconds' to the current value of obj.display.value at he start of startTimer() and make sure to give the seconds input a 'number' type and a starting value.
Also use clearInterval(Id) to stop the timer once its finished..
function startTimer()
{
var obj = document.getElementById("timer");
/* make sure to tell javascript that 'seconds' is Number that
comes from the input box */
var seconds;
seconds = Number(obj.display.value);
/* Don't need this *AND* seconds-- */
// seconds = seconds - 1;
if (seconds <= 0)
{
clearInterval(Id);
seconds = 0;
}
else
{
seconds--;
}
obj.display.value = seconds;
}
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<title>123</title>
<script type="text/javascript">
</script>
</head>
<body>
<form id="timer" action="#">
<p><input type="number" name="display" size="
20" value="30" /></p>
<!-- changed the interval from 100ms to 1000ms -->
<p><input type="button" value="Start"
onclick="Id=setInterval('startTimer()', 1000)" />
</form>
</script>
</body>
</html>
You can use something like this:
modify the number to whatever you want, if you want an input control then I assume you know how to do it, if not let me know.
function myFunction() {
var inputVal = document.getElementById('myInput').value;
var seconds = inputVal, $seconds = document.querySelector('#countdown');
(function countdown() {
$seconds.textContent = seconds + ' second' + (seconds == 1 ? '' : 's')
if(seconds --> 0) setTimeout(countdown, 1000)
})();
}
<input type="text" id="myInput" placeholder="Enter number..." >
<button onclick="myFunction()">Start Counter</button>
<span id="countdown"></span>
asign seconds at the top of the code...
<script type="text/javascript">
seconds =100;
<input type="number" id="inp">
<div id="counter"></div>
<script>
let input = document.getElementById('inp')
let counter = document.getElementById('counter')
let handleInput = e => {
let num = Number(e.target.value)
let _counter = num - 1
let timer = setInterval(_ => {
if(!_counter)
clearInterval(timer)
counter.innerText = _counter
_counter--
}, 1000)
}
input.addEventListener('input', handleInput)
</script>
The above logic works for 1 - 9 (single-digit input), you can add a debounce if you want to go for double-digit or greater numbers

Decrease input number in javascript

I just started learning javascript. I develop an input box that user enters a number in. so program decrease number to zero.
my problem is here; I enter a number and show same it in output, but show a decreasing number.
my JS code :
function test() {
var MyInput = parseInt(document.getElementById('HoursOfWork').value);
var Exp_MyInput = document.getElementById('output01').innerHTML = "Number: " + MyInput;
for (var i = 1; i < 4; i++) {
document.getElementById('output01').innerHTML = MyInput;
}
}
<!DOCTYPE html>
<html lang="en" xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta charset="utf-8" />
<link rel="stylesheet" href="StyleSheet.css" />
<script src="Script.js"></script>
<title>EyeProctect Project</title>
</head>
<body>
<h1>Eye Protect</h1>
<h4>Keep Your Eyes safe</h4>
<input type="text" id="HoursOfWork" placeholder="Enter your hours of work ...." />
<button class="start" onclick=test()>Let's Go!</button>
<p id="output01"></p>
</body>
</html>
What am I do?
If you meant counting down from number provided in input field down to zero using for loop then you can work with this approach:
function test() {
var MyInput = parseInt(document.getElementById('HoursOfWork').value);
var output = document.getElementById('output01');
output.innerHTML = '';
for (var i = MyInput; i > 0; i--) {
output.innerHTML += "Number: " + i + "<br>";
}
}

stop setTime from another function with local variable

thanks for helping!
The main goal of this is Stop the timer. But It does not work.
I know that this does not work because I am calling a local variable from another function but If I declare the variable as global the setTime starts automatically and It is not what I want.
How could a solve it, or another alternative? thanks!!
This is my code:
var interval2;
function startTimef(){
var startTime = Date.now();
interval2 = setInterval(function() {
var elapsedTime = Date.now() - startTime - 5000;
document.getElementById("timer").innerHTML = (elapsedTime / 1000).toFixed(3);
}, 75);
}
function myStopFunction(interval2) {
clearInterval(interval2); // does not work because interval2 is a local variable in StartTime.
var result = document.getElementById("result");
var score = document.getElementById("timer").textContent;
if (score < -0.200) { result.innerHTML = score+" Almost there ";}
if (score < -500 && score < -0.200) { result.innerHTML = "Almost there";}
if (score > -0.200 && score < 0 ) { result.innerHTML = "No too bad mate";}
if (score > -0.100 && score < 0.200 ) { result.innerHTML = "Perfect !!!";}
if (score > 0.200 ) { result.innerHTML = "You need some work!";}
};
// Press Enter Keyboard
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>TimeOver</title>
</head>
<body>
<div class="main-box">
<h2>Try to Stop the timer as close as possible to cero</h2>
<p id="timer">0000</p>
<button id="stop" onclick="myStopFunction()" >Stop time</button>
<span id="result"></span>
<button id="" onclick="startTimef()" >start</button>
</div>
<script src="main.js"></script>
</body>
</html>
Try this. Removing interval2 from myStopFunction(interval2) will work.
Your first approach will not since you have 2 interval2 variables and JS will use the locally declared interval2 instead of the outer interval2.
var interval2;
function startTimef(){
var startTime = Date.now();
interval2 = setInterval(function() {
var elapsedTime = Date.now() - startTime - 5000;
document.getElementById("timer").innerHTML = (elapsedTime / 1000).toFixed(3);
}, 75);
}
function myStopFunction() {
clearInterval(interval2);
var result = document.getElementById("result");
var score = document.getElementById("timer").textContent;
if (score < -0.200) { result.innerHTML = score+" Almost there ";}
if (score < -500 && score < -0.200) { result.innerHTML = "Almost there";}
if (score > -0.200 && score < 0 ) { result.innerHTML = "No too bad mate";}
if (score > -0.100 && score < 0.200 ) { result.innerHTML = "Perfect !!!";}
if (score > 0.200 ) { result.innerHTML = "You need some work!";}
};
// Press Enter Keyboard
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>TimeOver</title>
</head>
<body>
<div class="main-box">
<h2>Try to Stop the timer as close as possible to cero</h2>
<p id="timer">0000</p>
<button id="stop" onclick="myStopFunction()" >Stop time</button>
<span id="result"></span>
<button id="" onclick="startTimef()" >start</button>
</div>
<script src="main.js"></script>
</body>
</html>

Categories