stop setTime from another function with local variable - javascript

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>

Related

How to show the total increment of an app counter

Guys I wanna make an app which can count people, I have it according to the course but I'd like to add the total at the end not the previous entries.
enter image description here
let saveEl = document.getElementById("save-el")
let countEl = document.getElementById("count-el")
let count = 0
function counter() {
count += 1
countEl.textContent = count
}
function save() {
//let countStr = count + "-" caso eu não queira que volte do zero
let countStr = count + " - "
saveEl.textContent += countStr
countEl.textContent = 0
count = 0
}
console.log(count)
Instructions were not clear but I guess you want to "sum up the counts" instead of displaying them separately.
Here's a codepen achieving that, hopefully that works for you ;)
let saveEl = document.getElementById("save-el")
let countEl = document.getElementById("count-el")
let count = 0
function counter() {
count += 1
countEl.textContent = count
}
function save() {
let prevCount = saveEl.textContent ? parseInt(saveEl.textContent) : 0
saveEl.textContent = count + prevCount
countEl.textContent = 0
count = 0
}
<!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>Counter</title>
</head>
<body>
<h1>Members :</h1>
<button onClick=counter()>counter</button>
<button onClick=save()>save</button>
<p id="count-el"></p>
<hr/>
<p id="save-el"></p>
</body>
</html>

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>

how i am going to clearInterval when i press stop btn?

i am truly new with programing with javaScript so i just start to learn it, it will be good you are going to reply using a simple js code
my code does'nt stop when i press stop i want to clear the interval that i named with myTimer if i didn't put setInterval inside the function it just work directly and if there is any way to make my code more short please mentiot it.
const // my variable
myHour = document.getElementById("hours"),
myMin = document.getElementById("min"),
mySecond = document.getElementById("second"),
myMiliSecond = document.getElementById("dsecond"),
startchrono = document.getElementById("start"),
getLap = document.getElementById("lap"),
stopchrono = document.getElementById("stop"),
resetchrono = document.getElementById("reset"),
result = document.getElementById("result");
let // variable
milisecond = 0,
second = 0,
minute = 0,
hour = 0,
chronoRun = false,
round = 0;
function decoration(item) // this function is for add 0 if second or minute less than 10
{
if (String(item).length < 2) {
item = "0" + item;
}
return item;
}
function lapset() // function that create a new row in the table to save rounds
{
round++;
let // decoration add 0 if number under 10
ds = decoration(milisecond),
s = decoration(second),
m = decoration(minute),
h = decoration(hour);
if (round <= 10) {
const // insert the row in table
tr = result.insertRow(-1);
tr.insertCell(0).innerHTML = round;
tr.insertCell(-1).innerHTML = h + ":" + m + ":" + s + ":" + ds;
} else if (round <= 11) {
tr = result.insertRow(-1);
tr.insertCell(-0).innerHTML = "-";
tr.insertCell(-1).innerHTML = "you can't add any more laps";
getLap.setAttribute("disabled", "true");
}
}
function chrono() //chrono start
{
// chrono
milisecond++;
// make sure that minute, second have to be less than 60
if (milisecond > 10) {
milisecond = 0;
second++;
}
if (second > 59) {
second = 0;
minute++;
}
if (minute > 59) {
minute = 0;
hour++;
}
let // decoration add 0 if number under 10
ds = decoration(milisecond),
s = decoration(second),
m = decoration(minute),
h = decoration(hour);
myMiliSecond.innerHTML = ds;
mySecond.innerHTML = s;
myMin.innerHTML = m;
myHour.innerHTML = h;
startchrono.setAttribute("disabled", "true");
}
// function chronoStarts() {}
const myTimer = () => {
setInterval(chrono, 100);
};
const test = () => {
return clearInterval(myTimer);
};
startchrono.addEventListener("click", myTimer);
getLap.addEventListener("click", lapset);
stopchrono.addEventListener("click", test);
<!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>
</head>
<body>
<div id="chrono">
<div id="timer">
<span id="hours" class="time">00</span>
<span class="sep">:</span>
<span id="min" class="time">00</span>
<span class="sep">:</span>
<span id="second" class="time">00</span>
<span class="sep">:</span>
<span id="dsecond" class="time">00</span>
</div>
<div id="btnarea">
<button id="start" class="btnevent">start</button>
<button id="lap" class="btnevent">lap</button>
<button id="stop" class="btnevent">stop</button>
<button id="reset" class="btnevent">reset</button>
</div>
<table id="result">
<caption>saved lap</caption>
<tbody>
<tr>
<th class="round">round</th>
<th class="laptime">time</th>
</tr>
</tbody>
</table>
</div>
<script src="newpagescript.js"></script>
</body>
</html>
and that is my html code i think every is ok with my code but if there any issue i am looking for adives
You need to get the return value of the setInterval function and then pass that value as a parameter in the clearInterval function. For example, see below:
`// function chronoStarts() {}
let intervalId = 0;
const myTimer = () => {intervalId = setInterval(chrono, 100);};
const test = () => {
clearInterval(intervalId);
};
startchrono.addEventListener("click", myTimer);
getLap.addEventListener("click", lapset);
stopchrono.addEventListener("click", test);`

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.

Countdown with a delay in 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>

Categories