JavaScript timer doesn't start after being reset - javascript

The timer, start/pause button and reset button all work as expected.
The only bug it seems to have is, when I run the timer and reset it, it
won't start again. Only after I press the Start/Pause button 2 times it will run again.
Live demo: http://codepen.io/Michel85/full/pjjpYY/
Code:
var timerTime;
var time = 1500;
var currentTime;
var flag = 0;
var calculateTime
// Start your Timer
function startTimer(time) {
document.getElementById("btnUp").disabled = true;
document.getElementById("btnDwn").disabled = true;
timerTime = setInterval(function(){
showTimer();
return flag = 1;
}, 1000);
}
// Reset function
function resetTimer(){
clearInterval(timerTime);
document.getElementById('showTime').innerHTML=(calculateTime(1500));
document.getElementById("btnUp").disabled = false;
document.getElementById("btnDwn").disabled = false;
return time=1500;
}
// Pause function
function pauseTimer(){
clearInterval(timerTime);
currentTime = time;
document.getElementById('showTime').innerHTML=(calculateTime(time));
return flag = 0;
}
// Update field with timer information
function showTimer(){
document.getElementById("showTime").innerHTML=(calculateTime(time));
flag = 1;
if(time < 1){
resetTimer();
}
time--;
};
// Toggle function (Pause/Run)
function toggleTimmer(){
if(flag == 1){
pauseTimer();
} else {
startTimer();
}
}
/*
Round-time up or down
*/
// Set timer Up
function timeUp(){
time += 60;
document.getElementById("showTime").innerHTML=(calculateTime(time));
return time;
}
// Set timer Down
function timeDown(){
if(time > 60){
time-=60;
}
document.getElementById("showTime").innerHTML=(calculateTime(time));
return time;
}
/*
Break-time up down
*/
// Set timer Up
function breakUp(){
time += 60;
document.getElementById("showTime").innerHTML=(calculateTime(time));
return time;
}
// Set timer Down
function breakDown(){
if(time > 60){
time-=60;
}
document.getElementById("showTime").innerHTML=(calculateTime(time));
return time;
}
// Calculate the Days, Hours, Minutes, seconds and present them in a digital way.
function calculateTime(totalTime) {
// calculate days
var days = Math.floor(totalTime / 86400);
totalTime = totalTime % 86400
// calculate hours
var hours = Math.floor(totalTime / 3600);
totalTime = totalTime % 3600;
// calculate minutes
var minutes = Math.floor(totalTime / 60);
totalTime = totalTime % 60;
// calculate seconds
var seconds = Math.floor(totalTime);
function convertTime(t) {
return ( t < 10 ? "0" : "" ) + t;
}
// assign the variables
days = convertTime(days);
hours = convertTime(hours);
minutes = convertTime(minutes);
seconds = convertTime(seconds);
// Make sure the "00:" is present if empty.
if(days !== "00"){
var currentTimeString = days + ":" + hours + ":" + minutes + ":" + seconds;
return currentTimeString;
} else if (hours !== "00"){
var currentTimeString = hours + ":" + minutes + ":" + seconds;
return currentTimeString
} else if(minutes !== "0:00"){
var currentTimeString = minutes + ":" + seconds;
return currentTimeString
} else {
var currentTimeString = seconds;
return currentTimeString
}
}
Any help is welcome.
Thanks in advance.
Greets,
Michel

resetTimer needs to set flag to 0. If it leaves it set at 1, then toggleTimer will call pauseTimer rather than startTimer.
BTW, it's better style to use boolean values (true/false) for flags.

Just remove clearInterval(timerTime); in function resetTimer();
function resetTimer() {
//clearInterval(timerTime);
document.getElementById('showTime').innerHTML = (calculateTime(300));
document.getElementById("btnUp").disabled = false;
document.getElementById("btnDwn").disabled = false;
return time = 300;
}

Related

Countdown It does not Work with click button

I have a simple question. I want to make this code work with the Reset time button when the time is start again from 30 min delete the ( You are Ready! ) and start the time
var seconds = 30;
function secondPassed() {
var minutes = Math.round((seconds - 30) / 60);
var remainingSeconds = seconds % 60;
if (remainingSeconds < 10) {
remainingSeconds = "0" + remainingSeconds;
}
document.getElementById('countdown').innerHTML = minutes + ":" + remainingSeconds;
if (seconds == 0) {
clearInterval(countdownTimer);
document.getElementById('countdown').innerHTML = "You are Ready!";
} else {
seconds--;
}
}
var countdownTimer = setInterval('secondPassed()', 1000);
<span id="countdown" class="timer">
Reset time
I created a new function to reset the seconds and restart the timer and linked it to the button. I have also isolated at the start of the js code the variables that will count the seconds and hold the reference to the Interval.
is this what you are looking for?
var seconds;
var countdownTimer;
function startTimer() {
if (!seconds || seconds == 0) {
seconds = 30;
clearInterval(countdownTimer);
countdownTimer = setInterval(secondPassed, 1000)
secondPassed();
}
}
function secondPassed() {
var minutes = Math.round((seconds - 30) / 60);
var remainingSeconds = seconds % 60;
if (remainingSeconds < 10) {
remainingSeconds = "0" + remainingSeconds;
}
document.getElementById('countdown').innerHTML = minutes + ":" + remainingSeconds;
if (seconds == 0) {
clearInterval(countdownTimer);
document.getElementById('countdown').innerHTML = "You are Ready!";
} else {
seconds--;
}
}
startTimer();
<html>
<body>
<div>
<span id="countdown" class="timer"></span>
</div>
Reset time
</body>
</html>
Here create a separate function where after clicking - it disables the button, sets the timer, and changes button text.
In secondPassed method, if seconds == 0, it enables the button, so that you can start count down again.
var seconds = 30;
var countdownTimer;
function secondPassed() {
var minutes = Math.round((seconds - 30) / 60);
var remainingSeconds = seconds % 60;
if (remainingSeconds < 10) {
remainingSeconds = "0" + remainingSeconds;
}
document.getElementById('countdown').innerHTML = minutes + ":" + remainingSeconds;
if (seconds == 0)
{
clearInterval(countdownTimer);
document.getElementById('reset').disabled = false;
document.getElementById('countdown').innerHTML = "You are Ready!";
} else
{
seconds--;
}
}
function start(){
seconds = 30;
document.getElementById('reset').innerHTML = "Reset";
document.getElementById('reset').disabled = true;
countdownTimer = setInterval('secondPassed()', 1000);
}
//on load call
start();
<div>
<span id="countdown" class="timer"/>
</div>
<button id="reset" onclick="start()">
Start
</button>
Let's assume something quite basic, like the following:
<div>00:00</div>
<button>Reset</button>
Below is an approach you could take, fully-commented.
// We'll start by getting a couple element references
const label = document.querySelector("div");
const button = document.querySelector("button");
// Next, we'll bind-up the click handler for the button
button.addEventListener("click", () => {
// When the user clicks the button, we'll set the time
// limit to 30 minutes and proceed
let timer = 60 * 30;
// Disable the button to prevent further clicks
button.disabled = true;
button.dataset.default = button.textContent;
button.textContent = "Now counting down!";
// Let's setup some code that will be executed every second
button.interval = setInterval(() => {
// This decimal will be a number like 29.9521
const decimal = timer / 60;
// We'll convert 29.9521 into 29, for 29 minutes
const wholeMinute = Math.floor(decimal);
// Next, we'll take the .9521 and multiply by 60 for seconds
const wholeSecond = Math.round(60 * (decimal - wholeMinute));
// We'll pad both of the numbers so they always have a leading 0
const lblMin = wholeMinute.toString().padStart(2, 0);
const lblSec = wholeSecond.toString().padStart(2, 0);
// As long as we aren't out of seconds
if (timer >= 0) {
// Reduce the timer by 1 second
timer = timer - 1;
// And print the new label on our label element
label.textContent = `${ lblMin }:${ lblSec }`;
// Then return, so we don't execute what comes next
return;
}
// If we made it this far, our timer ran out
// Start by enabling the button
button.disabled = false;
// Restore the original text of the button
button.textContent = button.dataset.default;
// And clear our interval, as it is no longer needed
clearInterval(button.interval);
// Our interval will 'tick' once every second (1000 milliseconds)
}, 1000);
});

Why is my StopWatch not working

I have to create a stopwatch that has a start button, a stop button and a pause button. I have so far reached start and stop buttons but the are not working. What is the issue. I have to even go ahead and create a pause button , how to do that. Please help.
var seconds = 0,
minutes = 0,
hours = 0,
timer;
var toStop = false;
var h1 = document.getElementsByTagName('h1')[0];
function start() {
while (!toStop) {
seconds++;
if (seconds >= 60) {
seconds = 0;
minutes++;
if (minutes >= 60) {
minutes = 0;
hours++;
if (hours >= 12) {
hours = 0;
toStop = true;
stop();
}
}
}
document.getElementById("h").value = (hours ? (hours > 9 ? hours : "0" + hours) : "00") + ":" +
(minutes ? (minutes > 9 ? minutes : "0" + minutes) : "00") + ":" +
(seconds > 9 ? seconds : "0" + seconds);
myTimer();
}
}
function stop() {
clearTimeout(myTimer());
console.log(timer);
}
function myTimer() {
timer = setInterval(start, 1000);
console.log(timer);
}
function clear() {
document.getElementById("h").value = "00:00:00";
seconds = 0;
minutes = 0;
hours = 0;
}
<h1 id="h"><time>00:00:00</time></h1>
<button onclick="myTimer()">Start</button>
<button onclick="stop()">Stop</button>
<button onclick="clear()">Clear</button>
while (!toStop) {
Get rid of that. The start() func should just calc and print elapsed time. Also, don't call myTimer(); in start(). You already call setInterval() which will call start() every second.
Instead of calculating the elapsed time the way you do, you should create a Date object in myTimer(). Then in start() create another one. To calc elapsed time, subtract one from the other.
And since you call setInterval() you should call clearInterval() to stop.
var startTime = null;
var timer = null;
var totalTime = 0;
function getElapsedTime()
{
var now = new Date();
return (now - startTime) / 1000;
}
function start() {
// Calculate elapsed time since start btn was hit
var elapsedTime = getElapsedTime();
// Add prev times (from pause)
elapsedTime += totalTime;
// elapsedTime is in seconds. Calc, h/m/s
var hours = Math.floor(elapsedTime / (60 * 60));
elapsedTime %= (60 * 60);
var minutes = Math.floor(elapsedTime / 60);
elapsedTime %= 60;
var seconds = Math.floor(elapsedTime);
if (hours > 12) {
stop();
}
// Build string
var timeStr = (hours < 10 ? "0" : "") + hours + ":" +
(minutes < 10 ? "0" : "") + minutes + ":" +
(seconds < 10 ? "0" : "") + seconds;
// Update timer
document.getElementById("h").textContent = timeStr;
document.getElementById("h").value = timeStr;
}
var amPaused = false;
function pause()
{
if (amPaused) {
amPaused = false;
startTime = new Date();
timer = setInterval(start, 1000);
}
else {
amPaused = true;
totalTime += getElapsedTime();
if (timer) {
clearInterval(timer);
timer = null;
}
}
}
function stop() {
if (timer) {
clearInterval(timer);
timer = null;
}
amPaused = false;
document.getElementById("start").disabled = false;
document.getElementById("stop").disabled = true;
document.getElementById("pause").disabled = true;
}
function myTimer() {
stop();
totalTime = 0;
// Store the start time
startTime = new Date();
// Start the timer
timer = setInterval(start, 1000);
document.getElementById("start").disabled = true;
document.getElementById("stop").disabled = false;
document.getElementById("pause").disabled = false;
}
<h1><time id="h">00:00:00</time></h1>
<button onclick="myTimer()" id="start">▶</button>
<button onclick="stop()" id="stop" disabled="true">■</button>
<button onclick="pause()" id="pause" disabled="true">⏸</button>
<html>
<head>
<title>
Stop-Watch
</title>
</head>
<body>
<script>
var myCounter;
var seconds = 0, minutes = 0, hours = 0, timer;
var toStop = false;
var h1 = document.getElementsByTagName('h1')[0];
function start() {
if (!toStop) {
seconds++;
if (seconds >= 60) {
seconds = 0;
minutes++;
if (minutes >= 60) {
minutes = 0;
hours++;
if (hours >= 12) {
hours = 0;
toStop = true;
stop();
}
}
}
var time = (hours ? (hours > 9 ? hours : "0" + hours) : "00") + ":" +
(minutes ? (minutes > 9 ? minutes : "0" + minutes) : "00") + ":" +
(seconds > 9 ? seconds : "0" + seconds);
document.getElementById("h").innerHTML = time;
// myTimer();
}
}
function stop() {
toStop = true;
clearInterval(myCounter);
}
function myTimer() {
if (!toStop) {
document.getElementById("h").innerHTML = "00:00:00";
seconds = 0; minutes = 0; hours = 0;
}
clearInterval(myCounter);
toStop = false;
myCounter = setInterval(start, 1000);
}
function clearTime() {
toStop = true;
seconds = 0; minutes = 0; hours = 0;
clearInterval(myCounter);
document.getElementById("h").innerHTML = "00:00:00";
}
</script>
<h1>
<time id="h">00:00:00</time>
</h1>
<button onclick="myTimer()">Start</button>
<button onclick="stop()">Stop</button>
<button onclick="clearTime()">Clear</button>
</body>
</html>
Don't use while or any loops they block io events, so there is no chance for the browser to update html.
If you like to use loops then you could try async/await:
async start() {
while (!stop) {
await sleep(1000)
// some code to get elapsedTime
render()
}
}
function sleep(ms) {
return new Promise(resolve => {
setTimeout(() => resolve(), ms)
})
}
But I like to avoid to use loops for this task.
I believe it could be less coding and cleaner.
const timer = {
start() {
this.time = new Date()
clearInterval(this.interval)
this.interval = setInterval(() => { this.tick() }, 1000)
},
stop() {
clearInterval(this.interval)
},
reset() {
this.time = new Date()
clearInterval(this.interval)
this.render(0, 0, 0)
},
tick() {
const now = new Date()
const elapsedTime = new Date(now - this.time)
const hours = elapsedTime.getUTCHours()
const minutes = elapsedTime.getUTCMinutes()
const seconds = elapsedTime.getUTCSeconds()
if (hours >= 12) this.stop()
this.render(hours, minutes, seconds)
},
render(hours, minutes, seconds) {
const time = [hours, minutes, seconds].map(v => v.toString().padStart(2, `0`))
const html = document.getElementById(`timer`)
html.textContent = time.join(`:`)
}
}
<h1>
<time id="timer">00:00:00</time>
</h1>
<button onclick="timer.start()">Start</button>
<button onclick="timer.stop()">Stop</button>
<button onclick="timer.reset()">Reset</button>

Jquery pomodoro clock using setInterval() and clearInterval()

I'm working on a simple pomodoro clock project using JQuery. I've gotten to where I can get the time to display and countdown the way it should but I am having issues when the timer gets to zero. I can't seem to get the clock to stop and to display 00:00 and then start the break timer. Instead I'm getting a garbage number when the timer is over. When the session time gets to 0 the clock should clear and start the break timer.
I have created a codepen for this project so you can visualize the issue. https://codepen.io/nick_kinlen/full/Bdgdqp/
var working = true;
var breaking = false;
var workTime = .10;
var breakTime = 32.00;
var minutes;
var seconds;
$(document).ready(function(){
$('#start').click(function(){
initializeClock('#clock', minutes, seconds);
});
workTime = workTime * 60;
breakTime = breakTime * 60;
});
function initializeClock(id, minutes, seconds){
// set up initial display of clock
var clock = $('#clock');
clock.text(workTime);
// update time every second, if time is 0 stop timer
var timeInterval = setInterval(function(){
clock.text(minutes, seconds);
if(working === true) {
if(updateClock(minutes) < 0 && updateClock(seconds) < 0){
clearInterval(timeInterval);
working = false;
breaking = true;
alert('Hey this block of code is executing!');
}
else if(breaking === true){
if(updateClock(minutes) === 0 && updateClock(seconds) === 0){
clearInterval(timeInterval);
breaking = false;
working = true;
}
}
}
}, 1000);
}
function updateClock(time){
// subtract time from current time,
workTime--;
minutes = Math.floor(workTime % 3600 / 60);
seconds = workTime % 60;
// Adds a 0 in front of single digit minutes/seconds
minutes = ('0' + minutes).slice(-2);
seconds = ('0' + seconds).slice(-2);
// update clock
$('#clock').text(minutes + ':' + seconds);
console.log(minutes, seconds);
// If the block is on break time
if(breaking){
var minutes = Math.floor(breakTime % 3600 / 60);
var seconds = breakTime % 60;
breakTime--;
minutes = ('0' + minutes).slice(-2);
seconds = ('0' + seconds).slice(-2);
$('#clock').text(minutes + ':' + seconds);
}
}
// Add/subtract time to break
$('#subtractBreakMinute').click(function(){
if(breakTime > 0) {
breakTime -= 1;
$('#breakDisplay').text(breakTime);
}
})
$('#addBreakMinute').click(function(){
if(breakTime < 59) {
breakTime += 1;
$('#breakDisplay').text(breakTime);
}
})
// Add/subtract time to workTime
$('#subtractSessionMinute').click(function(){
if(workTime > 0) {
workTime -= 1;
$('#sessionDisplay').text(workTime);
}
})
$('#addSessionMinute').click(function(){
if(workTime < 59) {
workTime += 1;
$('#sessionDisplay').text(workTime);
}
})

how to prevent workTicker and breakTicker function to go into negative numbers

I'm working on a pomodoro clock. The application is almost done; however, when adding and subtracting numbers the number can go into negative. And that's not desire. The workTicker and breakTicker function are responsible for this. I implemented an if statement that check whether the number is > than 1. But when the number is = 1, it will no longer execute. How can I implement this? thanks codepen: https://codepen.io/zentech/pen/vJGdjN
javascript / jquery
$(document).ready(function() {
//variables
var session;
var seconds;
var minutes;
var clockDisplay = document.getElementById("display");
var counterId = 0;
var state = "work";
var start; //getting start time
//start / stop clock listener functionality
$("#start").click(function() {
var value = $(".button").text();
console.log(value);
if(value == "Start") {
session = Number($(".work").text() * 60);
start = new Date().getTime();
state = "work";
console.log("started!");
//starting counter
counterId = setInterval(countDown, 1000);
$("#session").text("Work");
$(".button").text("Stop");
} else {
console.log("stopped");
// | 0 same as Number()
session = (($(".work").text() * 60) | 0);
//clear counter
clearInterval(counterId);
clockDisplay.innerHTML = (session/60) +":00";
$("#session").text("Session");
$(".button").text("Start");
}
});
//add work time
$('.plusWork').click(function() {
var value = "plus";
console.log(value);
workTicker(value);
});
//substract work time
$('.minWork').click(function() {
var value = "minus";
workTicker(value);
});
//add break time
$('.plusBreak').click(function() {
var value = "plus";
breakTicker(value);
});
//substract break time
$('.minBreak').click(function() {
var value = "minus";
breakTicker(value);
});
//work countdown timer function
function countDown() {
//getting time now in ms
var now = new Date().getTime();
/*difference since clock started. now and start are in ms
we need to / by 1000 to bring to sec*/
var diff = Math.floor(session - ((now - start) / 1000));
console.log("diff: "+diff+" min: "+Math.floor(diff/60)+" sec: "+Math.floor(diff%60));
//getting minutes
minutes = Math.floor((diff / 60));
//getting seconds
seconds = Math.floor((diff % 60));
//dealing with minutes and sec under 10: 09, 07...
minutes = (minutes < 10) ? "0"+minutes : minutes;
seconds = (seconds < 10) ? "0"+seconds : seconds;
//update clock display
clockDisplay.innerHTML = minutes+":"+seconds;
//if difference reached < 0 stop counter;
if(diff == 0) {
restartSession(state);
}
}
//add substract work from timer/display
function workTicker(value) {
var min = Number($('.work').text());
//add substract while min > 0
if(min > 1) {
(value == "plus") ? min++ : min--;
clockDisplay.innerHTML = min+":00";
$(".work").text(min);
console.log(min);
}
}
//add substract break time
function breakTicker(value) {
var min = Number($(".break").text());
//add substract as long as min > 0
if(min > 1) {
(value == "plus") ? min++ : min--;
$(".break").text(min);
}
}
//restart countdown clock
function restartSession(state) {
//if state is work, change to break and visebersa
if(state == "work") {
alert("Stop working!");
$("#session").text("Break")
session = $(".break").text();
} else {
alert("Get to work!");
$("#session").text("Work");
session = $(".work").text();
}
clearInterval(counterId); //clear counter
console.log("session: "+session+" state: "+state);
start = new Date().getTime(); //setting start time
session = Number(session * 60); //converting min to sec
state = state == "work" ? "break" : "work";
counterId = setInterval(countDown, 1000); //starting counter
}
});
Try checking only if user is trying to subtract...
function breakTicker(value) {
var min = Number($(".break").text());
//add substract as long as min > 0
if(value == "plus") {
min++
} else {
if(min > 1){
min--;
}
}
$(".break").text(min);
}
Codepen: https://codepen.io/anon/pen/VzmLLd

Countup since a specific date in javascript/jQuery [duplicate]

I want to use a simple countdown timer starting at 30 seconds from when the function is run and ending at 0. No milliseconds. How can it be coded?
var count=30;
var counter=setInterval(timer, 1000); //1000 will run it every 1 second
function timer()
{
count=count-1;
if (count <= 0)
{
clearInterval(counter);
//counter ended, do something here
return;
}
//Do code for showing the number of seconds here
}
To make the code for the timer appear in a paragraph (or anywhere else on the page), just put the line:
<span id="timer"></span>
where you want the seconds to appear. Then insert the following line in your timer() function, so it looks like this:
function timer()
{
count=count-1;
if (count <= 0)
{
clearInterval(counter);
return;
}
document.getElementById("timer").innerHTML=count + " secs"; // watch for spelling
}
I wrote this script some time ago:
Usage:
var myCounter = new Countdown({
seconds:5, // number of seconds to count down
onUpdateStatus: function(sec){console.log(sec);}, // callback for each second
onCounterEnd: function(){ alert('counter ended!');} // final action
});
myCounter.start();
function Countdown(options) {
var timer,
instance = this,
seconds = options.seconds || 10,
updateStatus = options.onUpdateStatus || function () {},
counterEnd = options.onCounterEnd || function () {};
function decrementCounter() {
updateStatus(seconds);
if (seconds === 0) {
counterEnd();
instance.stop();
}
seconds--;
}
this.start = function () {
clearInterval(timer);
timer = 0;
seconds = options.seconds;
timer = setInterval(decrementCounter, 1000);
};
this.stop = function () {
clearInterval(timer);
};
}
So far the answers seem to rely on code being run instantly. If you set a timer for 1000ms, it will actually be around 1008 instead.
Here is how you should do it:
function timer(time,update,complete) {
var start = new Date().getTime();
var interval = setInterval(function() {
var now = time-(new Date().getTime()-start);
if( now <= 0) {
clearInterval(interval);
complete();
}
else update(Math.floor(now/1000));
},100); // the smaller this number, the more accurate the timer will be
}
To use, call:
timer(
5000, // milliseconds
function(timeleft) { // called every step to update the visible countdown
document.getElementById('timer').innerHTML = timeleft+" second(s)";
},
function() { // what to do after
alert("Timer complete!");
}
);
Here is another one if anyone needs one for minutes and seconds:
var mins = 10; //Set the number of minutes you need
var secs = mins * 60;
var currentSeconds = 0;
var currentMinutes = 0;
/*
* The following line has been commented out due to a suggestion left in the comments. The line below it has not been tested.
* setTimeout('Decrement()',1000);
*/
setTimeout(Decrement,1000);
function Decrement() {
currentMinutes = Math.floor(secs / 60);
currentSeconds = secs % 60;
if(currentSeconds <= 9) currentSeconds = "0" + currentSeconds;
secs--;
document.getElementById("timerText").innerHTML = currentMinutes + ":" + currentSeconds; //Set the element id you need the time put into.
if(secs !== -1) setTimeout('Decrement()',1000);
}
// Javascript Countdown
// Version 1.01 6/7/07 (1/20/2000)
// by TDavid at http://www.tdscripts.com/
var now = new Date();
var theevent = new Date("Sep 29 2007 00:00:01");
var seconds = (theevent - now) / 1000;
var minutes = seconds / 60;
var hours = minutes / 60;
var days = hours / 24;
ID = window.setTimeout("update();", 1000);
function update() {
now = new Date();
seconds = (theevent - now) / 1000;
seconds = Math.round(seconds);
minutes = seconds / 60;
minutes = Math.round(minutes);
hours = minutes / 60;
hours = Math.round(hours);
days = hours / 24;
days = Math.round(days);
document.form1.days.value = days;
document.form1.hours.value = hours;
document.form1.minutes.value = minutes;
document.form1.seconds.value = seconds;
ID = window.setTimeout("update();", 1000);
}
<p><font face="Arial" size="3">Countdown To January 31, 2000, at 12:00: </font>
</p>
<form name="form1">
<p>Days
<input type="text" name="days" value="0" size="3">Hours
<input type="text" name="hours" value="0" size="4">Minutes
<input type="text" name="minutes" value="0" size="7">Seconds
<input type="text" name="seconds" value="0" size="7">
</p>
</form>
Just modified #ClickUpvote's answer:
You can use IIFE (Immediately Invoked Function Expression) and recursion to make it a little bit more easier:
var i = 5; //set the countdown
(function timer(){
if (--i < 0) return;
setTimeout(function(){
console.log(i + ' secs'); //do stuff here
timer();
}, 1000);
})();
var i = 5;
(function timer(){
if (--i < 0) return;
setTimeout(function(){
document.getElementsByTagName('h1')[0].innerHTML = i + ' secs';
timer();
}, 1000);
})();
<h1>5 secs</h1>
Expanding upon the accepted answer, your machine going to sleep, etc. may delay the timer from working. You can get a true time, at the cost of a little processing. This will give a true time left.
<span id="timer"></span>
<script>
var now = new Date();
var timeup = now.setSeconds(now.getSeconds() + 30);
//var timeup = now.setHours(now.getHours() + 1);
var counter = setInterval(timer, 1000);
function timer() {
now = new Date();
count = Math.round((timeup - now)/1000);
if (now > timeup) {
window.location = "/logout"; //or somethin'
clearInterval(counter);
return;
}
var seconds = Math.floor((count%60));
var minutes = Math.floor((count/60) % 60);
document.getElementById("timer").innerHTML = minutes + ":" + seconds;
}
</script>
For the sake of performances, we can now safely use requestAnimationFrame for fast looping, instead of setInterval/setTimeout.
When using setInterval/setTimeout, if a loop task is taking more time than the interval, the browser will simply extend the interval loop, to continue the full rendering. This is creating issues. After minutes of setInterval/setTimeout overload, this can freeze the tab, the browser or the whole computer.
Internet devices have a wide range of performances, so it's quite impossible to hardcode a fixed interval time in milliseconds!
Using the Date object, to compare the start Date Epoch and the current. This is way faster than everything else, the browser will take care of everything, at a steady 60FPS (1000 / 60 = 16.66ms by frame) -a quarter of an eye blink- and if the task in the loop is requiring more than that, the browser will drop some repaints.
This allow a margin before our eyes are noticing (Human = 24FPS => 1000 / 24 = 41.66ms by frame = fluid animation!)
https://caniuse.com/#search=requestAnimationFrame
/* Seconds to (STRING)HH:MM:SS.MS ------------------------*/
/* This time format is compatible with FFMPEG ------------*/
function secToTimer(sec){
const o = new Date(0), p = new Date(sec * 1000)
return new Date(p.getTime()-o.getTime()).toString().split(" ")[4] + "." + p.getMilliseconds()
}
/* Countdown loop ----------------------------------------*/
let job, origin = new Date().getTime()
const timer = () => {
job = requestAnimationFrame(timer)
OUT.textContent = secToTimer((new Date().getTime() - origin) / 1000)
}
/* Start looping -----------------------------------------*/
requestAnimationFrame(timer)
/* Stop looping ------------------------------------------*/
// cancelAnimationFrame(job)
/* Reset the start date ----------------------------------*/
// origin = new Date().getTime()
span {font-size:4rem}
<span id="OUT"></span>
<br>
<button onclick="origin = new Date().getTime()">RESET</button>
<button onclick="requestAnimationFrame(timer)">RESTART</button>
<button onclick="cancelAnimationFrame(job)">STOP</button>
You can do as follows with pure JS. You just need to provide the function with the number of seconds and it will do the rest.
var insertZero = n => n < 10 ? "0"+n : ""+n,
displayTime = n => n ? time.textContent = insertZero(~~(n/3600)%3600) + ":" +
insertZero(~~(n/60)%60) + ":" +
insertZero(n%60)
: time.textContent = "IGNITION..!",
countDownFrom = n => (displayTime(n), setTimeout(_ => n ? sid = countDownFrom(--n)
: displayTime(n), 1000)),
sid;
countDownFrom(3610);
setTimeout(_ => clearTimeout(sid),20005);
<div id="time"></div>
Based on the solution presented by #Layton Everson I developed a counter including hours, minutes and seconds:
var initialSecs = 86400;
var currentSecs = initialSecs;
setTimeout(decrement,1000);
function decrement() {
var displayedSecs = currentSecs % 60;
var displayedMin = Math.floor(currentSecs / 60) % 60;
var displayedHrs = Math.floor(currentSecs / 60 /60);
if(displayedMin <= 9) displayedMin = "0" + displayedMin;
if(displayedSecs <= 9) displayedSecs = "0" + displayedSecs;
currentSecs--;
document.getElementById("timerText").innerHTML = displayedHrs + ":" + displayedMin + ":" + displayedSecs;
if(currentSecs !== -1) setTimeout(decrement,1000);
}
// Javascript Countdown
// Version 1.01 6/7/07 (1/20/2000)
// by TDavid at http://www.tdscripts.com/
var now = new Date();
var theevent = new Date("Nov 13 2017 22:05:01");
var seconds = (theevent - now) / 1000;
var minutes = seconds / 60;
var hours = minutes / 60;
var days = hours / 24;
ID = window.setTimeout("update();", 1000);
function update() {
now = new Date();
seconds = (theevent - now) / 1000;
seconds = Math.round(seconds);
minutes = seconds / 60;
minutes = Math.round(minutes);
hours = minutes / 60;
hours = Math.round(hours);
days = hours / 24;
days = Math.round(days);
document.form1.days.value = days;
document.form1.hours.value = hours;
document.form1.minutes.value = minutes;
document.form1.seconds.value = seconds;
ID = window.setTimeout("update();", 1000);
}
<p><font face="Arial" size="3">Countdown To January 31, 2000, at 12:00: </font>
</p>
<form name="form1">
<p>Days
<input type="text" name="days" value="0" size="3">Hours
<input type="text" name="hours" value="0" size="4">Minutes
<input type="text" name="minutes" value="0" size="7">Seconds
<input type="text" name="seconds" value="0" size="7">
</p>
</form>
My solution works with MySQL date time formats and provides a callback function. on complition.
Disclaimer: works only with minutes and seconds, as this is what I needed.
jQuery.fn.countDownTimer = function(futureDate, callback){
if(!futureDate){
throw 'Invalid date!';
}
var currentTs = +new Date();
var futureDateTs = +new Date(futureDate);
if(futureDateTs <= currentTs){
throw 'Invalid date!';
}
var diff = Math.round((futureDateTs - currentTs) / 1000);
var that = this;
(function countdownLoop(){
// Get hours/minutes from timestamp
var m = Math.floor(diff % 3600 / 60);
var s = Math.floor(diff % 3600 % 60);
var text = zeroPad(m, 2) + ':' + zeroPad(s, 2);
$(that).text(text);
if(diff <= 0){
typeof callback === 'function' ? callback.call(that) : void(0);
return;
}
diff--;
setTimeout(countdownLoop, 1000);
})();
function zeroPad(num, places) {
var zero = places - num.toString().length + 1;
return Array(+(zero > 0 && zero)).join("0") + num;
}
}
// $('.heading').countDownTimer('2018-04-02 16:00:59', function(){ // on complete})
var hr = 0;
var min = 0;
var sec = 0;
var count = 0;
var flag = false;
function start(){
flag = true;
stopwatch();
}
function stop(){
flag = false;
}
function reset(){
flag = false;
hr = 0;
min = 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(flag == true){
count = count + 1;
setTimeout( 'stopwatch()', 10);
if(count ==100){
count =0;
sec = sec +1;
}
}
if(sec ==60){
min = min +1 ;
sec = 0;
}
if(min == 60){
hr = hr +1 ;
min = 0;
sec = 0;
}
var hrs = hr;
var mins = min;
var secs = sec;
if(hr<10){
hrs ="0" + hr;
}
if(min<10){
mins ="0" + min;
}
if(sec<10){
secs ="0" + sec;
}
document.getElementById("hr").innerHTML = hrs;
document.getElementById("min").innerHTML = mins;
document.getElementById("sec").innerHTML = secs;
document.getElementById("count").innerHTML = count;
}

Categories

Resources