I'm trying to create a function that can return a value (the user's current time in seconds) to another variable that can be used elsewhere in my code. The function returns the correct value, but I can't figure out how to make it repeat using setInterval or setTimeout.
var currenttime = clock();
function clock() {
var now = new Date();
var hour = now.getHours();
var minute = now.getMinutes();
var second = now.getSeconds();
var time = (hour * 3600) + (minute * 60) + second;
return time;
}
console.log(currenttime)
I want the variable currenttime to be updated every second, but changing the line to
var currenttime = setInterval(clock, 1000);
returns an incorrect value. Alternatively I've also tried to make the clock function repeat,
but I'm not sure how to do this as I'm using a return statement so the function ends before it can be repeated.
Does anyone know what I'm doing wrong?
Assign to currentTime every time clock runs, but don't return the time - since this'll be in an interval, the return value is ignored:
let currentTime;
function clock() {
var now = new Date();
var hour = now.getHours();
var minute = now.getMinutes();
var second = now.getSeconds();
currentTime = (hour * 3600) + (minute * 60) + second;
}
setInterval(clock, 1000);
setTimeout(() => console.log(currentTime), 2000);
setTimeout(() => console.log(currentTime), 6000);
This is a bit weird, though - variable assignment alone doesn't have side effects (in almost all cases). It would make more sense for whatever uses the currentTime variable to call clock to get the current number of seconds, eg:
function clock() {
var now = new Date();
var hour = now.getHours();
var minute = now.getMinutes();
var second = now.getSeconds();
return (hour * 3600) + (minute * 60) + second;
}
document.querySelector('button').addEventListener('click', () => {
document.querySelector('div').textContent = clock();
});
<button>Get seconds</button>
<div id="time"></div>
The function called by setInterval should call clock and display the time.
setInterval(function(){ console.log(clock()); }, 1000);
setInterval return only an ID value that can be used in clearInterval(ID) to stop setInterval loop.
So, you can do that:
function clock()
{
let [h,m,s] = (new Date().toTimeString()).match(/\d{2}/g)
return (h*3600) + (m*60) + +s
}
var currenttime = clock();
setInterval(() => { currenttime = clock() }, 1000);
Related
having difficulty stopping timer outside of loop. I don't really know why the setTimeout() has been helping the function work... and i know its not the most syntactically correct.. but wondering if someone can help point me as to how to be able to call it outside the function to stop the countdown, say if an action occurs before the timer, and want to call a stopCountdown() function?
function countdown(start){
setTimeout(setCountdown, 1000);
let startingMinutes = timerEl.innerHTML;
startingMinutes = start;
let time = startingMinutes * 60;
function setCountdown(){
const minutes = Math.floor(time/60);
let seconds = time % 60;
if(seconds < 10){
seconds = '0' + seconds
} else {
seconds
}
if(minutes <=0 && seconds <=0){
clearInterval(start);
console.log('timerOver')
} else{
setTimeout(setCountdown, 1000);
timerEl.innerHTML = (minutes + ':'+seconds)
time--;
}
}}
function stopCountdown(){
document.querySelector("#countdown").innerText = '0'
setTimeout(setCountdown(start));
}
Welcome to coding, I am trying my best to explain it. First, let me point out some of my opinion on your code
function countdown(start){
setTimeout(setCountdown, 1000);
let startingMinutes = timerEl.innerHTML;
startingMinutes = start;
// I am not sure why you firstly initializing startMinutes
// to the value of timerEl.innerHTML
//and then reassign the value of startMinutes to variable start next line
let time = startingMinutes * 60;
function setCountdown(){
const minutes = Math.floor(time/60);
let seconds = time % 60;
if(seconds < 10){
seconds = '0' + seconds
} else {
seconds
}
if(minutes <=0 && seconds <=0){
clearInterval(start); // you are using setTimeout, not setInterval
console.log('timerOver')
} else{
setTimeout(setCountdown, 1000);
timerEl.innerHTML = (minutes + ':'+seconds)
time--;
}
}}
function stopCountdown(){
document.querySelector("#countdown").innerText = '0'
setTimeout(setCountdown(start));
// when calling stopCountdown(), what is the value of start?
// you can't access function setCountdown inside function stopCountdown
}
If my guess is correct, you want to make a timer and then you can make it stop when calling a stopCountdown function, right?
For a timer, it is simply asking javascript to - 1 seconds for every 1000 ms passed. So we can write a function which -1 seconds and ask JS to run it every 1000ms, right?
In this case, you should use setInterval but not setTimeout (setTimeout can also make a timer, I will also show you). The difference is that setTimeout calls a function ONCE after X milliseconds and setInterval will run a function EVERY X milliseconds.
Here is the code
let countdownIntervalId // get the countdownIntervalId outside by first declearing a variable to catch the id
function countdown(start) { // assume the unit of start is minute
console.log("countdown called, minutes =" + start)
// add code here to change the innerHTML of the timer if you want
let secondsToCount = start * 60; //Converting minutes to seconds
countdownIntervalId = setInterval(() => {
timer()
}, 1000); // starting to count down
function timer() { // run every seconds
const minutes = Math.floor(secondsToCount / 60);
let seconds = secondsToCount - minutes*60;
console.log("counter= " + minutes + ':' + `${seconds}`.padStart(2, '0'))
secondsToCount = secondsToCount-1;
if (minutes <= 0 && seconds <= 0) {
clearInterval(countdownIntervalId); // clearInterval
console.log('timerOver')
}
}
}
function stopCountdownOutside(){
if(countdownIntervalId){
clearInterval(countdownIntervalId)
}
}
countdown(2) //countdown 2 mins
You can stop the counter by calling stopCountdownOutside(), you can test on Chrome console. This is because we are passing the intervalId to the countdownIntervalId which is declare outside the function. so we can simply call clearInterval(countdownIntervalId) to stop it
For using the setTimeout
let countdownTimeoutId// get the countdownIntervalId outside by first declearing a variable to catch the id
function countdown(start) { // assume the unit of start is minute
console.log("countdown called, minutes =" + start)
// add code here to change the innerHTML of the timer if you want
let secondsToCount = start * 60; //Converting minutes to seconds
countdownTimeoutId = setTimeout(() => {
timer()
}, 1000); // starting to count down
function timer() { // run every seconds
const minutes = Math.floor(secondsToCount / 60);
let seconds = secondsToCount - minutes*60;
console.log("counter= " + minutes + ':' + `${seconds}`.padStart(2, '0'))
secondsToCount = secondsToCount-1;
if (minutes <= 0 && seconds <= 0) {
clearTimeout(countdownTimeoutId); // clearTimeout
console.log('timerOver')
}else{
countdownTimeoutId = setTimeout(timer,1000)
}
}
}
function stopCountdownOutside(){
if(countdownTimeoutId){
clearTimeout(countdownTimeoutId)
}
}
countdown(1) //countdown 2 mins
you can try to refactor my code to a more clean version, happy coding
Im working on code for a simple stopwatch. Last obstacle for me is reset the time to zero. The function resetTimer is where i am trying to implement the code. So the webpage will display a page with a timer and three buttons; stop, start and reset. When a user clicks the reset button, the timer is supposed to reset back to zero. I have been having trouble trying to make it work. Any help/ideas would be clutch.
I hope i made myself clear. Again i am trying to make the timer reset to 00:00:00
window.onload = function () {
//grab possible elements needed
const timerEl = document.getElementById("timer-text")
const startBtn = document.getElementById("start")
const restartBtn = document.getElementById("restart");
const stopBtn = document.getElementById('stop');
//hold variables of time and set to 0
let hours = parseInt('0');
let minutes = parseInt('0');
let seconds = parseInt('0');
let time;
function makeTwoNumbers(num) {
if (num < 10) {
return "0" + num
}
return num
}
//timer
let timer = () => {
seconds++
//console.log(seconds)
if (seconds == 60) {
minutes++
seconds = 0;
hours = 0
}
if (minutes == 60) {
hours++
minutes = 0;
hours = 0;
}
timerEl.textContent = makeTwoNumbers(hours)+ ": " + makeTwoNumbers(minutes) + ": " + makeTwoNumbers(seconds);
}
let runTheClock;
//timer is running
function runTimer() {
runTheClock = setInterval(timer, 20);;
}
function stopTimer() {
clearInterval(runTheClock)
}
//function will reset timer
function resetTimer() {
time--;
timerEl.textContent;
if (time === 0) {
stopTimer();
time = 0
}
}
restartBtn.addEventListener("click", function () {
resetTimer();
})
//button will pause the timer
stopBtn.addEventListener("click", function () {
stopTimer();
})
//button will start the timer
startBtn.addEventListener("click", function () {
runTimer();
})
}
Here's a fixed and slightly refactored version.
<html>
<body>
<div id="timer-text"></div>
<button id="start">start</button>
<button id="restart">restart</button>
<button id="stop">stop</button>
</body>
<script>
const timerEl = document.getElementById("timer-text")
const startBtn = document.getElementById("start")
const restartBtn = document.getElementById("restart");
const stopBtn = document.getElementById('stop');
let runTheClock;
let seconds = 0;
render(seconds);
function makeTwoNumbers(num) {
return ((num < 10) ? "0" : "") + num;
}
function tick() {
seconds++;
render(seconds);
}
function render(secs) {
const hours = Math.floor(secs / 3600);
const minutes = Math.floor(secs / 60) - (hours * 60);
const seconds = secs % 60;
const val = [hours, minutes, seconds].map(makeTwoNumbers).join(":");
console.log(val);
timerEl.textContent = val;
}
function runTimer() {
runTheClock = setInterval(tick, 1000);
}
function stopTimer() {
clearInterval(runTheClock)
}
function resetTimer() {
seconds = 0;
render(seconds);
}
restartBtn.addEventListener("click", resetTimer);
stopBtn.addEventListener("click", stopTimer);
startBtn.addEventListener("click", runTimer);
</script>
</html>
In the reset function it just sets seconds back to 0 and sets the textContent value so it appears on the page. I separated out the calculating and drawing of the time into a render fucntion, so it can be reused whenever it needs to be re-rendered.
To explain the render function.
We only need to store the number of seconds as a persistent variable between the periodic function calls. We can derive hours and minutes from it. This makes it much less error prone than trying to increment hours and minutes as well.
To calculate hours we just divide seconds by 3600 (or 60 x 60 the number of seconds in an hour) and round down.
To calculate minutes we can calculate the number of total minutes (seconds / 60 and round down) then subtract the number of minutes in the hours value we calculated (hours * 60).
For seconds we use modulus or % which is just a fancy word for remainder. So seconds % 60 gives us the remainder value of seconds / 60. For example 61 % 60 = 1. This isn't the only way these values could be calculated.
To build the display string. I just put all of the hours, minutes and seconds in an array. Then used the map method, which applies the function makeTwoNumbers to all of the values. I then used the join method to join all the strings using the delimiter :. It just saves some typing and means you only reference makeTwoNumbers once, making it less work to use a different function later if you want to.
Hope that helps.
I realized that you could simply reset seconds, hours, and minutes to 0 and use a variable true. This would reset it entirely to 0. I couldnt believe how simple it was
I'm trying to create a pomodoro clock, and I can't figure out why the resetClock function is going everything except clearing the interval for the clock. It is resetting the number, but the clock keeps counting down. I'd imagine I'll have this issue when trying to implement the stop clock function also. Can someone help?
var minutes = 25;
var seconds = 0;
var startSound = new Audio('./sounds/startsound.mp3')
var resetSound = new Audio('./sounds/resetclocksound.mp3')
var stopSound = new Audio('./sounds/pausesound.mp3')
var alarmSound = new Audio('/sounds//haoduken.mp3')
var minutes_interval;
var seconds_interval;
function startClock() {
startSound.play();
minutes = 24;
seconds = 59;
document.getElementById('minutes').innerHTML = minutes;
document.getElementById('seconds').innerHTML = seconds;
document.getElementById('start-button').removeEventListener('click', startClock)
var minutes_interval = setInterval(minutesTimer, 60000);
var seconds_interval = setInterval(secondsTimer, 1000);
function minutesTimer() {
minutes = minutes - 1;
document.getElementById('minutes').innerHTML = minutes;
}
function secondsTimer() {
seconds = seconds - 1;
document.getElementById('seconds').innerHTML = seconds;
if (seconds <= 0) {
seconds = 60;
}
if (seconds <= 0 && minutes <= 0) {
alarmSound.play()
clearInterval(minutes_interval);
clearInterval(seconds_interval);
}
}
}
function resetClock() {
clearInterval(seconds_interval);
clearInterval(minutes_interval)
resetSound.play();
var minutes = 25;
var seconds = 0;
document.getElementById('minutes').innerHTML = minutes;
document.getElementById('seconds').innerHTML = seconds;
document.getElementById('start-button').addEventListener('click', startClock)
}
The problem is on the lines where you start the interval:
var minutes_interval = setInterval(minutesTimer, 60000);
var seconds_interval = setInterval(secondsTimer, 1000);
the problem is simply your use of the var keyword, which creates a new local variable inside the startClock function. It does nothing to the outer (global?) variables of the same name, because those are "shadowed" by the new local variables.
As a consequence, the clearInterval calls inside resetClock are referencing the outer variables, which do not hold a timer ID.
The solution is probably very simple: just remove the var from the above two lines. You now only have one "global" minutes_interval and seconds_interval, which will be referenced by the clearInterval calls. From a quick glance, it appears that this should work OK for you, and that you only ever set these intervals up once before cancelling them. But if you wanted to use this code to set up multiple intervals simultaneously you'd have to rethink your approach.
function getTime() {
const d = new Date();
const secs = d.getSeconds();
const mins = d.getMinutes();
const hours = d.getHours();
return {
'hours': hours,
'mins': mins,
'secs': secs
}
}
let time = getTime();
setInterval(getTime, 1000);
setInterval(() => {
console.log(`${time.hours}:${time.mins}:${time.secs}`);
}, 1000);
The time displayed doesn't change. It just continually runs, outputting the same time instead of showing a change each second...
time variable is declared only once, when script loads and stays in that state. Move it inside the interval to keep it updated.
function getTime() {
const d = new Date();
const secs = d.getSeconds();
const mins = d.getMinutes();
const hours = d.getHours();
return {
'hours': hours,
'mins': mins,
'secs': secs
}
}
setInterval(() => {
const time = getTime();
console.log(`${time.hours}:${time.mins}:${time.secs}`);
}, 1000);
You are only setting the value of time once, to the value of getTime() at that moment.
If you want the value to change, you have to set the value again every iteration.
setInterval(() => {
var time = getTime();
console.log(`${time.hours}:${time.mins}:${time.secs}`);
}, 1000);
That's because you are not updating the time variable, but just calling getTime in setInterval.
This is how it should be:
setInterval(function() {
time = getTime();
console.log(`${time.hours}:${time.mins}:${time.secs}`);
}, 1000);
Note:
If you declare your time variable as constant with cons keyword, trying to change it will throw this error:
Uncaught TypeError: Assignment to constant variable.
Demo:
function getTime() {
const d = new Date();
const secs = d.getSeconds();
const mins = d.getMinutes();
const hours = d.getHours();
return {
'hours': hours,
'mins': mins,
'secs': secs
}
}
var time = getTime();
setInterval(function() {
time = getTime();
console.log(`${time.hours}:${time.mins}:${time.secs}`);
}, 1000);
Time is not changing because you are using variable which are not getting updated.
Here are two problems
const time = getTime();//its called once and time values are const
will never change again
setInterval(getTime, 1000);//here function is getting executed but
return value is never used and never assigned to time variable which
is printed.
function getTime() {
const d = new Date();
const secs = d.getSeconds();
const mins = d.getMinutes();
const hours = d.getHours();
return {
'hours': hours,
'mins': mins,
'secs': secs
}
}
//const time = getTime();//its called once and time values are const will never change again
//setInterval(getTime, 1000);//here function is getting executed but return value is never used and never assigned to time variable which is printed.
setInterval(() => {
var time=getTime();
//getTime
console.log(`${time.hours}:${time.mins}:${time.secs}`);
}, 1000);
I'm fairly new to DOM and the whole HTML and PHP Stuff so I'm seeking some information on how to do this. What I have until now is a Javascript. Now I want/have to use DOM to show this script. (FYI: I'm implementing something for Moodle and this has be done like this)
What I have found out about DOM is that I can change values of different Nodes. The problem I've found myself in is that all the examples I found were like. Click on a button and something happens. That's ok but now I want my script to run every second so I can the person who needs it can see that the time is running down.
I hope I gave you enough information and I hope you can help me. Thank you for trying to help me.
var running = false
var endTime = null
var timerID = null
// totalMinutes the amount of minutes is put into
var totalMinutes = 3;
function startTimer() {
// running is being started and the current time is put into the variable
running = true
now = new Date()
now = now.getTime()
// Variable endTime gets the time plus the maximum time
endTime = now + (1000 * 60 * totalMinutes);
showCountDown()
}
function showCountDown() {
// same as startTimer, time is saved in variable now
var now = new Date()
now = now.getTime()
if (endTime - now <= 0) {
// Variable timerID gets clearTimeout -->http://de.selfhtml.org/javascript/objekte/window.htm#clear_timeout
clearTimeout(timerID)
// boolean running set to false
running = false
alert("Ihr Resultat wird nun ausgewertet!")
} else {
// delta is being calculated
var delta = new Date(endTime - now)
var theMin = delta.getMinutes()
var theSec = delta.getSeconds()
var theTime = theMin
// show seconds and minutes
theTime += ((theSec < 10) ? ":0" : ":") + theSec
document.getElementById('CheckResults').innerHTML = " (Übung in " + theTime + " Minuten abgelaufen)"
if (running) {
timerID = setTimeout("showCountDown()",900)
}
}
}
</script>
You might want to use window.setInterval for a start. Here is a short example. Create a blank html page, put the script into the head section, and the markup into the body section. I wasn't able to post it with proper html and body tags
<script>
function countDownTimer(msecGranularity, output) {
var secRunningTime, startTime, endTime, onFinish, interval;
function heartBeat() {
var diff = endTime - new Date();
output.innerHTML = diff / 1000;
if (diff < 0) {
window.clearInterval(interval);
onFinish();
};
};
this.start = function (secRunningTime, finishHandler) {
onFinish = finishHandler;
startTime = new Date();
endTime = startTime.setSeconds(startTime.getSeconds() + secRunningTime);
interval = window.setInterval(heartBeat, msecGranularity);
}
};
function startTimer(duration, granularity) {
var output = document.createElement("div");
document.getElementById("timerOutputs").appendChild(output);
var t = new countDownTimer(granularity, output);
t.start(duration, function () { output.innerHTML = 'TIMER FINISHED' });
};
</script>
In the HTML place these to start the timer class.
<button onclick="startTimer(60,100)">Start a new 60 seconds timer with 100 msec granularity</button><br />
<button onclick="startTimer(600,1000)">Start a new 600 seconds timer with 1000 msec granularity</button>
<div id="timerOutputs">
</div>