Does `document.getElementById` break the function? - javascript

So I am working on a pomodoro timer and can't figure out what I am doing wrong with my JS. Overview of the project is here : http://codepen.io/Ohillio/pen/wMoNWy
But the specific part of the code I am having issues with is :
// global variables
var min = 0;
var sec = 0;
function tick() {
alert("Counter Started");
sec = 59;
min--;
document.getElementById("timer").innerHTML = min + ":" + sec;
do {
sec--
document.getElementById("timer").innerHTML = min + ":" + sec;
setTimeout(donothing,500);
}
while (sec != 0);
}
The issue is that it seems like it ends the function after the first time through. I want the seconds to tick down to 0, but now it just evaluates to 58.
Does document.getElementById break the function ?

Using setInterval may be a better solution to what you're trying to do. It's going to be more accurate and easy to short circuit once you hit 0. Also, I prefer to keep the total time in seconds and only use minutes for display purposes. I've put together an example for you to review.
<script>
var interval;
var totalSeconds = 1500;
function tick() {
totalSeconds--;
min = Math.floor(totalSeconds / 60);
sec = totalSeconds % 60;
document.getElementById('timer').innerHTML = min + ':' + sec;
if (0 >= totalSeconds) {
clearInterval(interval);
}
}
interval = setInterval(tick, 1000);
</script>
Hope this helps and good luck!

This also should work, with 1 digit second format fix:
var min = 1;
var sec = 30;
function tick() {
document.getElementById("timer").innerHTML = min + ":" + (sec.toString().length < 2 ? '0' : '') + sec;
if(sec === 0 && min > 0) {
min--;
sec = 59;
setTimeout(tick, 500);
} else if (sec > 0) {
sec--;
setTimeout(tick, 500);
} else {
alert("Done!");
}
}
alert("Counter Started");
tick();

Related

Repeat timer infinite amount of times

I am trying to add a countdown timer to my Shopify checkout using Google Optimize. I got this to work using the following HMTL & JS. Taken from here
However once the timer finishes and I reload the page it starts from 17 seconds instead of 5 minutes.
Is there a way to get this to repeat the timer from 5 minutes once it hits 0?
document.getElementById('timer').innerHTML =
05 + ":" + 00;
startTimer();
function startTimer() {
var presentTime = document.getElementById('timer').innerHTML;
var timeArray = presentTime.split(/[:]+/);
var m = timeArray[0];
var s = checkSecond((timeArray[1] - 1));
if(s==59){m=m-1}
if(m<0){
return
}
document.getElementById('timer').innerHTML =
m + ":" + s;
console.log(m)
setTimeout(startTimer, 1000);
}
function checkSecond(sec) {
if (sec < 10 && sec >= 0) {sec = "0" + sec}; // add zero in front of numbers < 10
if (sec < 0) {sec = "59"};
return sec;
}
<div>Your cart is reserved for <span id="timer"></span></div>
If you could give the answer like you are talking to a complete beginner it would be greatly appreciated.
Looks like I have a lot to learn!
Welcome to StackOverflow. This should help out...
//JAVASCRIPT
startTimer(5); // SPECIFY AMOUNT OF MINUTES OR NO PARAMETER FOR DEFAULT 5
function startTimer(minutes = 5){
var timeout = minutes * 60000;
var ms = timeout;
var interval = setInterval(function(){
ms -= 1000;
if(ms >= 0) {
var d = new Date(1000*Math.round(ms/1000));
document.getElementById('timer').innerHTML = getMS(d);
} else {
startTimer(5); // MAKE TIMER RESTART AGAIN FOR 5 MINS
// clearInterval(interval); // TO MAKE TIMER STOP UPON REACHING 0:00
}
}, 1000);
}
function getMS(d){
return pad(d.getUTCMinutes()) + ':' + pad(d.getUTCSeconds());
}
function pad(i) {
return ('0'+i).slice(-2);
}
<!--HTML -->
<body>
<div>Your cart is reserved for <span id="timer"></span></div>
</body>
In javascript the setInterval function allow you to make anything you want every fixed ms.
interval = setInterval(() => {
console.log('Waited for 5m');
// Do whatever you want
console.log('Waiting for 5m again...');
}, 300000);
// To stop the interval
clearInterval(interval);

Javascript stop countdown

I have a countdown in js and I can't add a trick I would like.
When the counting ends, it does not stop. Negative numbers start and instead I would like it to stop at 0 once the time has expired. How can I?
var counter = null;
window.onload = function() {
initCounter();
};
function initCounter() {
// get count from localStorage, or set to initial value of 1000
count = getLocalStorage('count') || 1000;
counter = setInterval(timer, 1000); //1000 will run it every 1 second
}
function setLocalStorage(key, val) {
if (window.localStorage) {
window.localStorage.setItem(key, val);
}
return val;
}
function getLocalStorage(key) {
return window.localStorage ? window.localStorage.getItem(key) : '';
}
function timer() {
count = setLocalStorage('count', count - 1);
if (count == -1) {
clearInterval(counter);
return;
}
var seconds = count % 60;
var minutes = Math.floor(count / 60);
var hours = Math.floor(minutes / 60);
minutes %= 60;
hours %= 60;
document.getElementById("countdown").innerHTML = hours + " ore " + minutes + " min " + seconds + " sec";
}
The problem is that you were putting count with -1 value in LocalStorage.
count = setLocalStorage('count', count - 1);
And after page reload you kept subtracting 1 from -1 and you got -2, which your condition count == -1 couldn't catch. Solution is to put next count value in LocalStorage after you check if need to continue your timer or not.
<script type="text/javascript">
let count = 0;
let counter = null;
window.onload = function() {
initCounter();
};
function initCounter() {
// get count from localStorage, or set to initial value of 1000
count = Number(getLocalStorage('count')) || 5;
counter = setInterval(timer, 1000); //1000 will run it every 1 second
}
function setLocalStorage(key, val) {
if (window.localStorage) {
window.localStorage.setItem(key, val);
}
return val;
}
function getLocalStorage(key) {
return window.localStorage ? window.localStorage.getItem(key) : '';
}
function timer() {
const nextCount = count - 1
if (nextCount < 0) {
clearInterval(counter);
return;
}
count = setLocalStorage('count', nextCount);
const seconds = count % 60;
let minutes = Math.floor(count / 60);
let hours = Math.floor(minutes / 60);
minutes %= 60;
hours %= 60;
document.getElementById("timer").innerHTML = hours + " ore " + minutes + " min " + seconds + " sec";
}
</script>
<div id="timer"></div>
Hope it helps :)
Change this:
if (count == -1) {
clearInterval(counter);
return;
}
To this:
if (count < 0) {
clearInterval(counter);
localStorage.removeItem('count');
return;
}
Always make your conditions as strict as you can, or you will run into trouble. You don't actually care that it's equal to -1. You care that it's below 0.
In your original code, it stops fine when the page is loaded without localStorage. But at the end, you set the localStorage to -1. When you refresh, you set it to -2 (count - 1) and start the counter going into the negatives. Your condition is never checked against that -1 value which was stored.

How to fix javascript timer so that seconds run up to 60 and then reset to zero

I'm setting up a timer, but currently the seconds run into the thousands instead of resetting to zero after 60 seconds. Is there a quick fix for this?
This is the code I'm using:
var running = 0;
function startPause(){
if(running == 0){
running = 1;
increment();
document.getElementById("start").innerHTML = "Pause";
}else{
running = 0;
document.getElementById("start").innerHTML = "Resume";
}
};
function reset(){
running = 0;
time = 0;
document.getElementById("output").innerHTML = "00:00";
document.getElementById("start").innerHTML = "Start";
};
function increment(){
if(running == 1){
setTimeout(function(){
time++;
var mins = Math.floor(time / 10 / 60);
if(mins <= 9){
mins = "0" + mins;
}
var secs = Math.floor(time / 10);
if(secs <= 9){
secs = "0" + secs;
}
document.getElementById("output").innerHTML = mins + ":" + secs;
increment();
}, 100);
}};
You can use modulo % 60.
It gives the Rest of the division by 60
example 127 % 60 = 7
I made a custom audio player and this helped me.
if (seconds != 0 && seconds % 60 == 0) {
seconds = 0;
minutes++;
}

How to stop the timer once you end an exam?

I want to stop this timer when I end the exam, but before it reaches zero. Kindly help me out on scripts please. Thanks.
JavaScript code:
var cnt = 165*60; // 165 minutes (2 hours & 45 minutes) convert to seconds
function countdown() {
if (cnt < 0) {
document.f.c.value = "- : - - : - -" ;
}
else {
hour = Math.floor(cnt / 3600);
totalmin = Math.floor(cnt / 60);
min = totalmin - (hour * 60);
sec = cnt - (totalmin * 60);
if (sec < 10) { sec = "0" + sec;}
if (min < 10) {min = "0" + min;}
if (hour < 10) {hour = "0" + hour;}
document.f.c.value = hour + ":" + min + ":" + sec;
cnt--;
_timer = setTimeout("countdown()", 1000);
}
}
var _timer = setTimeout("countdown()", 1000); // tick
I assume you meant that you want to end the timer before the countdown reaches 0.
First of all, you should use setInterval instead. It should work in all major browsers (including IE). It is just a slightly nicer way to express "I want this to happen every so often." According to the MDN, it:
Calls a function repeatedly, with a fixed time delay between each call to that function.
Here's how you would use it:
var cnt = 165*60; // 165 minutes (2 hours & 45 minutes) convert to seconds
function countdown() {
if (cnt < 0) {
document.f.c.value = "- : - - : - -" ;
}
else {
hour = Math.floor(cnt / 3600);
totalmin = Math.floor(cnt / 60);
min = totalmin - (hour * 60);
sec = cnt - (totalmin * 60);
if (sec < 10) {sec = "0" + sec;}
if (min < 10) {min = "0" + min;}
if (hour < 10) {hour = "0" + hour;}
document.f.c.value = hour + ":" + min + ":" + sec;
cnt--;
if(cnt <= 0) { # Stops the timer when it reaches 0.
clearInterval(_interval);
}
}
}
var _interval = setInterval(countdown, 1000);
And somewhere in your page have a button that will stop the timer.
<input type="button" value="Done" onclick="clearInterval(_interval)">
Although to be honest, having a countdown timer freaks me out. I'd rather have a count-up timer. :-)
In your else part
check
if(current_time < total_time)
{
//Set TimeOut
}
I think your best bet here is to use setInterval rather than setTimeout.
setInterval returns a handle to the interval. clearInterval(handle) will cancel that interval. Here's some pseudo to get you started:
var global_timer;
function countdown(){
// do some countdown stuff
if([we're done]) {
window.clearInterval(global_timer);
}
}
global_timer = window.setInterval("countdown()", 1000);
In the code that you execute when user ends the exam, probably after button click, just add such line:
window.clearTimeout(_timer);
And the timer will stop ticking.

Using JQuery replaceWith with a JavaScript Variable

Here's my html:
<div class="timer">Not Started</div>
And JS/JQ:
var seconds = 10;
var minutes = 0;
setTimeout("updateTimer()", 1000);
function updateTimer() {
if (seconds == 0 && minutes != 0) {
minutes -= minutes;
seconds = 59;
alert (seconds);
} else if (seconds == 1 && minutes == 0) {
alert ('done');
} else {
seconds = seconds - 1;
//alert (seconds);
$(".timer").replaceWith(seconds);
}
setTimeout("updateTimer()", 1000);
}
Instead of replacing Not Started with 10, 9, 8..., Not Started disappears.
$(".timer").text(seconds);
You can't replace a DOM node with a string.
See an example.
You could simplify your logic further by making use of setInterval instead of setTimeout, and use total seconds for easier calculations and remove minutes.
var seconds = 10, minutes = 0;
var totalSeconds = (minutes * 60) + seconds;
var timerId = setInterval(updateTimer, 1000);
function updateTimer() {
$('.timer').text(totalSeconds % 60);
if (totalSeconds == 0) {
alert("done");
clearInterval(timerId);
}
totalSeconds--;
}
replaceWith will replace the entire div, not just the contents. Try this instead:
$(".timer").html(seconds);

Categories