I've made a timer in JavaScript, but when the start button is repeatedly clicked it keeps getting faster. I know clearInterval is used to stop this, but depending on where I put it in the code it either stops the timer from working completely or makes no difference. This is the code, I put it on the fourth line but it's not doing anything:
var minutes;
var seconds;
function PomodoroBreak(x){
clearInterval(interval)
minutes = x;
seconds = 0;
var interval = setInterval(
function(){
var el = document.getElementById("timer")
if(seconds ==0 && minutes==0){
clearInterval(interval)
el.innerHTML = "00:00"
}
else if(seconds == 0){
minutes = minutes -1;
seconds = 59
el.innerHTML = minutes + ":" + seconds
}else if(seconds > 0){
seconds = seconds -1;
el.innerHTML = minutes + ":" + seconds
document.title = minutes + ":" + seconds
}
},
1000
)
}
Where am I supposed to put it instead, or have I done something else wrong? Thank you!
I'm seeing some adjustments to be done here. I believe returning clearInterval with the startTimer declared above should do the work.
Hope this helps.
function PomodoroBreak(x){
var minutes = x;
var seconds = 0;
let startTimer = setInterval(...,1000)
return clearInterval(startTimer)
}
I think you should declare the variable “interval“ outside the function. And remove the var in the function.
var minutes;
var seconds;
var interval;
function PomodoroBreak(x){
clearInterval(interval)
minutes = x;
seconds = 0;
interval = setInterval(
function(){
var el = document.getElementById("timer")
if(seconds ==0 && minutes==0){
clearInterval(interval)
el.innerHTML = "00:00"
}
else if(seconds == 0){
minutes = minutes -1;
seconds = 59
el.innerHTML = minutes + ":" + seconds
}else if(seconds > 0){
seconds = seconds -1;
el.innerHTML = minutes + ":" + seconds
document.title = minutes + ":" + seconds
}
},
1000
)
}
Related
I made a simple little timer with a start, reset, plus a nonfunctional stop button. All the documentation that I have read on it makes it seem very simple so I have no idea what's going wrong.
the stop.onclick function is getting read, but it only works for a second before it gets overwritten by the setInterval function
ps- I intend to improve the accuracy so please no hints on how best to do that
const start = document.getElementById("button1")
const stop = document.getElementById("stop")
const reset = document.getElementById("reset")
var clock = start.onclick = function(){
let seconds = 1
let minutes = 0
setInterval(function() {
if (minutes == 0){
if (seconds < 10)
timer.innerHTML = '0:0' + seconds++;
else
timer.innerHTML = '0:' + seconds++;
if (seconds == 60){
minutes++
seconds = 0
}
}
else {
if (seconds < 10)
timer.innerHTML = minutes + ':0' + seconds++;
else
timer.innerHTML = minutes + ':' + seconds++;
if (seconds == 60){
minutes++
seconds = 0
}
}
}, 1000);
reset.onclick = function(){
seconds = 0
}
stop.onclick = function(){
let display = seconds
timer.innerHTML = display
clearInterval(clock)
// alert("You stopped the clock!")
}
}
```
The problem is that that is not how setInterval and clearInterval work. Specifically, you don't pass clearInterval the function that you have running at some interval to clear the interval. Instead, setInterval returns a reference to the process; you can then pass that reference to clearInterval to clear it. For instance:
const myIntervalProcess = setInterval(() => console.log('hi'), 1000);
setTimeout(() => clearInterval(myIntervalProcess), 5000);
What we see above is that we set a function that logs "hi" to the console every second. We save the reference returned from setInterval to a variable called myIntervalProcess. Then we set a timeout to pass myIntervalProcess to clearInterval after five seconds. If you run this you can see that "hi" will be logged to console exactly five times, after which point it will cease.
If we apply this fix to your code we get:
const start = document.getElementById("button1")
const stop = document.getElementById("stop")
const reset = document.getElementById("reset")
var clock = start.onclick = function(){
let seconds = 1
let minutes = 0
const clockProcess = setInterval(function() {
if (minutes == 0){
if (seconds < 10)
timer.innerHTML = '0:0' + seconds++;
else
timer.innerHTML = '0:' + seconds++;
if (seconds == 60){
minutes++
seconds = 0
}
}
else {
if (seconds < 10)
timer.innerHTML = minutes + ':0' + seconds++;
else
timer.innerHTML = minutes + ':' + seconds++;
if (seconds == 60){
minutes++
seconds = 0
}
}
}, 1000);
reset.onclick = function(){
seconds = 0
}
stop.onclick = function(){
let display = seconds
timer.innerHTML = display
clearInterval(clockProcess)
// alert("You stopped the clock!")
}
}
Also, for what it's worth, you may wish to use a linter on your code-- I see some missing semicolons and other errors/inconsistencies it would help you catch and resolve. Good luck!
I have this Javascript count down timer that works perfectly. Only problem is i can use it for only one time in one page. I want to use it multiple times.
I think script use id ="timer" that is why i am not able to use it multiple times.
Below is the JS code:
<script>
var startTime = 60; //in Minutes
var doneClass = "done"; //optional styling applied to text when timer is done
var space = ' ';
function startTimer(duration, display) {
var timer = duration,
minutes, seconds;
var intervalLoop = setInterval(function() {
minutes = parseInt(timer / 60, 10)
seconds = parseInt(timer % 60, 10);
minutes = minutes < 10 ? "0" + minutes : minutes;
seconds = seconds < 10 ? "0" + seconds : seconds;
display.textContent = "00" + space + minutes + space + seconds;
if (--timer < 0) {
document.querySelector("#timer").classList.add(doneClass);
clearInterval(intervalLoop);
}
}, 1000);
}
window.onload = function() {
var now = new Date();
var hrs = now.getHours();
var setMinutes = 60 * (startTime - now.getMinutes() - (now.getSeconds() / 100)),
display = document.querySelector("#timer");
startTimer(setMinutes, display);
};
</script>
Just declare intervalLoop outside of the startTimer function, it'll be available globally.
var intervalLoop = null
function startTimer(duration, display) {
intervalLoop = setInterval(function() { .... }
})
function stopTimer() {
clearInterval(intervalLoop) // Also available here!
})
window.setInterval(function(){ Your function }, 1000);
Here 1000 means timer 1 sec
I think something like this could be helpful:
Timer object declaration
var timerObject = function(){
this.startTime = 60; //in Minutes
this.doneClass = "done"; //optional styling applied to text when timer is done
this.space = ' ';
return this;
};
timerObject.prototype.startTimer = function(duration, display) {
var me = this,
timer = duration,
minutes, seconds;
var intervalLoop = setInterval(function() {
minutes = parseInt(timer / 60, 10)
seconds = parseInt(timer % 60, 10);
minutes = minutes < 10 ? "0" + minutes : minutes;
seconds = seconds < 10 ? "0" + seconds : seconds;
display.textContent = "00" + me.space + minutes + me.space + seconds;
if (--timer < 0) {
// not sure about this part, because of selectors
document.querySelector("#timer").classList.add(me.doneClass);
clearInterval(intervalLoop);
}
}, 1000);
}
Use it like
var t1 = new timerObject();
var t2 = new timerObject();
t1.startTimer(a,b);
t2.startTimer(a,b);
JS Fiddle example:
UPD1 commented part so the the timer could be stopped
https://jsfiddle.net/9fjwsath/1/
// This timer keeps reseting back to 2:00 after it reaches 1 minute. Also i do not get a notification that says times up at the right time. Can someone please correct the code. Also the stop/resume timer button also has to stay functional.
var isRunning = false;
var ticker; //this will hold our setTimeout
var seconds,
minutes;
function countdown(mins, secs) {
//i made these global, so we can restart the timer later
seconds = secs || 60; //if user put in a number of minutes, use that. Otherwise, use 60
minutes = mins;
console.log('time stuff',mins,secs,minutes,seconds)
function tick() {
var counter = document.getElementById("timer");
var current_minutes = mins - 1
seconds--;
counter.innerHTML =
current_minutes.toString() + ":" + (seconds < 10 ? "0" : "") + String(seconds);
if (seconds < 1 && minutes) {
//seconds reached 0, and still minutes left;
seconds=60;
minutes--;
}
if ((seconds > 0 || minutes > 0) && isRunning) {
ticker = setTimeout(tick, 1000);
} else if(isRunning){
console.log(seconds,minutes,isRunning)
alert('Time\'s up, brah!')
}
}
tick();
}
function timeToggle() {
isRunning = !isRunning; //if it's false, set it true. If it's true, set it false.
if (!isRunning) {
clearTimeout(ticker); //or whatever else you set the initial timeOut to.
} else {
//not running! and time is defined;
var sec = seconds||60;
console.log('def!',minutes, sec)
countdown(minutes, sec);
}
}
isRunning = true;
countdown(2);
<div id="timer">2:00</div>
<button onclick="timeToggle()">Stop time</button>
There is a small flaw in your logic.
During the countdown initialization your doing
seconds = secs || 60;
Which effectively add 60 seconds to the time you want if you don't initialize the seconds. see:
function countdownInit(mins, secs) {
seconds = secs || 60;
minutes = mins;
console.log(mins + 'min ' + seconds + 'sec');
}
countdownInit(1, 30) // ok
// 1min 30sec
countdownInit(1) // not ok
// 1min 60sec
// thats 2 minutes
The second issue here is that you use a var current_minutes that equals minutes - 1 to display the time. So you are not showing the real counter.
the fix is as follow:
function countdown(mins, secs) {
seconds = secs;
minutes = mins;
// if secs is 0 or uninitialized we set seconds to 60 and decrement the minutes
if(!secs) {
minutes--;
seconds = 60;
}
function tick() {
var counter = document.getElementById("timer");
seconds--;
// we use minutes instead of current_minutes in order to show what's really in our variables
counter.innerHTML =
minutes.toString() + ":" + (seconds < 10 ? "0" : "") + String(seconds);
// rest of code
}
// rest of code
}
I tried to keep as much as your code as possible.
I have this countdown timer. For some reason it stops counting after one minute - it just stops.
If I count for 55 minutes it stops at 54:00
If I count for 2 minutes it stops at 1:00
Any ideas how do I fix that so it continues up to zero?
Here is the JSFiddle link: Countdown timer with cookies
And the JS code:
function countdown(minutes) {
var seconds = 60;
var mins = minutes;
if(getCookie("minutes")&&getCookie("seconds"))
{
var seconds = getCookie("seconds");
var mins = getCookie("minutes");
}
function tick() {
var counter = document.getElementById("timer");
setCookie("minutes",mins,10)
setCookie("seconds",seconds,10)
var current_minutes = mins-1
seconds--;
counter.innerHTML =
current_minutes.toString() + ":" + (seconds < 10 ? "0" : "") + String(seconds);
//save the time in cookie
if( seconds > 0 ) {
setTimeout(tick, 1000);
} else {
if(mins > 1){
// countdown(mins-1); never reach “00″ issue solved:Contributed by Victor Streithorst
setTimeout(function () { countdown(mins - 1); }, 1000);
}
}
}
tick();
}
function setCookie(cname,cvalue,exdays) {
var d = new Date();
d.setTime(d.getTime() + (exdays*24*60*60*1000));
var expires = "expires=" + d.toGMTString();
document.cookie = cname+"="+cvalue+"; "+expires;
}
function getCookie(cname) {
var name = cname + "=";
var ca = document.cookie.split(';');
for(var i=0; i<ca.length; i++) {
var c = ca[i];
while (c.charAt(0)==' ') c = c.substring(1);
if (c.indexOf(name) == 0) {
return c.substring(name.length, c.length);
}
}
return "";
}
countdown(55);
I don't know why you are using the cookies here but, putting that aside, your problem seems to be the following lines:
var seconds = getCookie("seconds");
var mins = getCookie("minutes");
In your code after you finished the first minute you call the countdown function again with a minute less. However, the lines above returns the minute variable back to its previous value. So you end up stuck in the same minute after one minute pass.
So, I assume, you need to get the time from the cookies only once (first time the countdown runs). You can use something like this:
var firstTime = true;
function countdown(minutes) {
var seconds = 60;
var mins = minutes;
if(firstTime && getCookie("minutes")&&getCookie("seconds"))
{
firstTime = false;
seconds = getCookie("seconds");
mins = getCookie("minutes");
}
...
Note that var is unnecessary in the if clause since you already
defined seconds and mins variables.
Code with day:hours:minute:second support.
Just add number of minutes into timer span.
For one day test, I entered 1440 minutes.
<html>
<body>
<span id="countdown" class="timer">1440</span>
<script type="text/javascript">
var first_time = true;
var countdownTimer;
var seconds = document.getElementById('countdown').innerHTML * 60;
//alert(seconds);
if(!isNaN(seconds) && seconds > 0 ) {
function timer() {
if(first_time) {
countdownTimer = setInterval('timer()', 1000);
first_time = false;
}
var days = Math.floor(seconds/24/60/60);
var hoursLeft = Math.floor((seconds) - (days*86400));
var hours = Math.floor(hoursLeft/3600);
var minutesLeft = Math.floor((hoursLeft) - (hours*3600));
var minutes = Math.floor(minutesLeft/60);
var remainingSeconds = seconds % 60;
if (remainingSeconds < 10) {
remainingSeconds = "0" + remainingSeconds;
}
document.getElementById('countdown').innerHTML = (days < 10 ? "0" : "") + days + ":" + (hours < 10 ? "0" : "") + hours + ":" + (minutes < 10 ? "0" : "") + minutes + ":" + (remainingSeconds < 10 ? "0" : "") + remainingSeconds;
if (seconds == 0) {
clearInterval(countdownTimer);
document.getElementById('countdown').innerHTML = "Completed";
} else {
seconds--;
}
}
timer()
//var countdownTimer = setInterval('timer()', 1000);
}
</script>
</body>
</html>
I'm trying to build a Pomodoro clock like http://codepen.io/GeoffStorbeck/full/RPbGxZ/. The value of seconds goes to NaN randomly and then returns to normal after starting 'break'.
$('#circle a').click(function() {
var timer = $('.time > span').html();
timer = timer.split(':');
var minutes = timer[0]; //Value of minutes
var seconds = timer[1]; //Value of seconds
var settimer = setInterval(function() {
seconds -= 1;
console.log(seconds);
if (seconds < 0 && minutes != 0) {
minutes -= 1;
minutes = String(minutes);
seconds = 59;
} else if (seconds < 10 && seconds.length != 2)
seconds = '0' + seconds;
if (minutes < 10 && minutes.length < 2)
minutes = '0' + minutes;
$('.time > span').html(minutes + ':' + seconds);
//Start break when session is completed
if (minutes == 0 && seconds == 0) {
$('.upper').find('h1').text('BREAK');
var time = $('#break').find('span').text();
$('.time > span').html('0' + time + ':00');
$('#circle a').trigger("click"); //Start timer for break
}
}, 1000);
});
Here's the link to the codepen
http://codepen.io/ibrahimjarif/pen/wMKJWN
How do I fix the NaN issue?
And is there any better way to implement this?
The code $('#circle a').trigger("click"); //Start timer for break recursively calls the function that was executing originally. This call starts a new timer while the original one was in progress.
The seconds value for the original timer went to NaN when the new timer was executing. There were two values for second due to two timers. The value of seconds in the original timer caused the unexplained appearance of NaN.
NOTE: Both the timers were running simultaneously all the time.
The simplest fix was to stop the current timer before starting a new one.
Here's the updated code
$('#circle a').click(function() {
var timer = $('.time > span').html().split(':');;
var minutes = Number(timer[0]),
seconds = Number(timer[1]);
var settimer = setInterval(function() {
seconds -= 1;
if (seconds < 0 && minutes != 0) {
minutes -= 1;
seconds = 59;
} else if (seconds < 10 && seconds.length != 2)
seconds = '0' + seconds;
if (minutes < 10 && minutes.toString().length < 2)
minutes = '0' + minutes;
$('.time > span').html(minutes + ':' + seconds);
if (minutes == 0 && seconds == 0) {
clearInterval(settimer); //Stop the current timer
var upper_text = $('.upper').find('h1');
var time;
if (upper_text.text() == 'BREAK') {
upper_text.text('Session');
time = $('#session').find('span').text();
} else {
upper_text.text('BREAK');
time = $('#break').find('span').text();
}
$('.time > span').html(time + ':00');
$('#circle a').trigger("click"); //Start new timer
}
}, 1000);
});