Javascript Pomodoro Clock - clearInterval not working when timer is 0 - javascript

I am making a simple podomoro clock, and everything seems to work fine except when timer reaches 0 its doesn't entirely stop. Minutes seem to stop but seconds keep decrementing. I think there might be something wrong with my startTimer function but I've tried tinkering with it for hours to no result.
JS:
$(document).ready(function() {
var pomoTime = $('#pomodoroNum');
var breakTime = $('#breakNum');
var status = $('#timerStatus');
var timerDisplay = $('#timer');
var startButton = $('#startBtn');
var stopButton = $('#stopBtn');
var state = 1; // 1=stopped 2=running
var countDown; // intervalID;
var minutes = 0;
var seconds = 60;
startButton.click(function() {
if (state == 1) { // if timer is not running then start timer
startTimer(minutes, seconds);
$('#breakMinus').off("click");
$('#breakPlus').off("click");
$('#workMinus').off("click");
$('#workPlus').off("click"); // disable +- controls when timer starts
};
});
updateDisplay(); // initially controls are enabled at the start
stopButton.on("click", function() {
if (state == 2) {
pauseTimer();
state = 1;
updateDisplay(); // renable +- controls when timer stops
}
});
function startTimer(m, s) {
state = 2;
var startMinutes = m;
var startSeconds = s;
countDown = setInterval(function() {
startSeconds--;
startMinutes = ("0" + startMinutes).slice(-2); // double digits conversion if <10
startSeconds = ("0" + startSeconds).slice(-2);
minutes = ("0" + startMinutes).slice(-2); // update minutes and seconds so when timer is stopped, it can resume from where it left off when startButton is pressed.
seconds = ("0" + startSeconds).slice(-2);
timerDisplay.html(startMinutes + ":" + startSeconds);
if (startSeconds == 0 && startMinutes > 0) {
startMinutes-- // decerement minutes when seconds 0...
startSeconds = 60; // ..and reset seconds to 60
}
}, 1000);
if (startMinutes == 0 && startSeconds == 0) {
clearInterval(countDown);// <-- not clearing here
}
};
function pauseTimer() {
clearInterval(countDown);
};
function updateDisplay() {
// break +-
$('#breakMinus').on("click", function() {
status.html("Break");
if (breakTime.text() > 1) {
breakTime.text(+breakTime.text() - 1);
};
timerDisplay.text(breakTime.text());
});
$('#breakPlus').on("click", function() {
status.html("Break");
breakTime.text(+breakTime.text() + 1); // parseInt to covert string into number so it doesn't concatanate.
timerDisplay.text(breakTime.text());
});
// work +-
$('#workMinus').on("click", function() {
status.html("Work");
if (pomoTime.text() > 1) {
minutes = pomoTime.text() - 2;
}
seconds = 60;
if (pomoTime.text() > 1) {
pomoTime.text(+pomoTime.text() - 1);
};
timerDisplay.text(pomoTime.text());
});
$('#workPlus').on("click", function() {
minutes = pomoTime.text();
seconds = 60;
status.html("Work");
pomoTime.text(+pomoTime.text() + 1); // parseInt to covert string into number to prevent concatanation.
timerDisplay.html(pomoTime.html());
});
};
});
example: http://codepen.io/aliz16/pen/OXMwRJ

Your check for the stop condition is outside of your interval function. That's why it's never stopping. Move the condition inside the function and use <= to be extra safe:
if (startSeconds <= 0 && startMinutes > 0) {
startMinutes -= 1; // decerement minutes when seconds 0...
startSeconds += 60; // ..and reset seconds to 60
}
if (startMinutes <= 0 && startSeconds <= 0) {
clearInterval(countDown);
}
}, 1000);

Related

Create a simple 2 minutes countdown

I want to make a count of 2 minutes, but I want to give you click to the button "Start", so far, and managed to make it work, but I have an error in the minutes does not run as well back but that appears NaN:seconds.
I show them the code that i am working on.
var timeoutHandle;
function countdown(minutes) {
var seconds = 60;
var mins = minutes
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 > 0 ) {
timeoutHandle=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);
}
document.getElementById("timer").innerHTML = "Finished"
}
}
tick();
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.0/jquery.min.js"></script>
<div class="tempo-completo">
<div id="timer">2:00</div>
<button onclick="countdown()">INICIAR</button>
</div>
You are not passing in the number of minutes to the countdown() function.
var timeoutHandle;
function countdown(minutes) {
var seconds = 60;
var mins = minutes
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 > 0 ) {
timeoutHandle=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);
}
document.getElementById("timer").innerHTML = "Finished"
}
}
tick();
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.0/jquery.min.js"></script>
<div class="tempo-completo">
<div id="timer">2:00</div>
<button onclick="countdown(2)">INICIAR</button>
</div>
Jeremy Harris' answer is working perfectly fine, but i would like to propose another one.
Don't use setTimeout to make an interval function, use setInterval. Using setTimeout with a recursive loop is overall less precise
With that in mind i've tweek your code to incorporate this idea.
var timeoutHandle;
function countdown(minutes) {
var seconds = 60;
var mins = minutes
var counter = document.getElementById("timer");
var current_minutes = mins-1
// we create an interval variable to clear it later
// we also use an arrow function to have access to variable
// outside of the current function's scope.
let interval = setInterval(() => {
seconds--;
counter.innerHTML =
current_minutes.toString() + ":" + (seconds < 10 ? "0" : "") + String(seconds);
// our seconds have run out
if(seconds <= 0) {
// our minutes have run out
if(current_minutes <= 0) {
// we display the finished message and clear the interval so it stops.
counter.innerHTML = "Finished"
clearInterval(interval);
} else {
// otherwise, we decrement the number of minutes and change the seconds back to 60.
current_minutes--;
seconds = 60;
}
}
// we set our interval to a second.
}, 1000);
}
<div class="tempo-completo">
<div id="timer">2:00</div>
<button onclick="countdown(2)">INICIAR</button>
</div>

Delay in timer when tab is inactive or browser minimised

I have the following code to show a timer for an online quiz application.On completion , I need to redirect to another page via ajax.
The code works for me,but I found that the timer delays when we shift tabs or minimise the browser.
var mins = 5;
var secs = 0; // Seconds (In addition to min) test time
var timerDisplay = $(document).find('#timerspan');
//Globals:
var timeExpired = false;
// Test time in seconds
var totalTime = secs + (mins * 60);
var countDown = function (callback) {
var interval;
interval = setInterval(function () {
if (secs === 0) {
if (mins === 0) {
timerDisplay.text('0:00');
clearInterval(interval);
callback();
return;
} else {
mins--;
secs = 60;
}
}
var minute_text;
if (mins > 0) {
minute_text = mins;
} else {
minute_text = '0';
}
var second_text = secs < 10 ? ('0' + secs) : secs;
timerDisplay.text(minute_text + ':' + second_text);
secs--;
}, 1000, timeUp);
};
// When time elapses: submit form
var timeUp = function () {
alert("Time's Up!");
timeExpired = true;
var completed=1;
$.ajax({
type:"POST",
url:"success.php",
data:{'userID':<?php echo $_SESSION['userID'];?>},
success: function (hasil) {
$('.response_div').html(hasil);
}
});
};
// Start the clock
countDown(timeUp);

how could I implement break time countdown using same function pomodoro clock

I'm working on a pomodoro clock and functionality is almost done, except I'm having difficulty implementing breakTime countdown without rewriting countDown() function just for breakTime. I got the impression I can reuse countDown function for break time. I just don't know how. If someone could give me some clues / code? thanks Project https://codepen.io/zentech/pen/vJGdjN
Javascript
$(document).ready(function() {
//variables
var workTime = $(".work").text(); //working time
var breakTime = $(".break").text(); //break time
var seconds = 00;
var minutes = workTime; //setting clock = to workTime
var clockDisplay = document.getElementById("display");
var counterId = 0;
var state = "on";
//start / stop listener functionality
$("#start").click(function() {
var value = $(".button").text();
console.log(value);
if(value == "Start") {
state = "on";
console.log("started!");
//starting counter
counterId = setInterval(countDown, 1000);
$("#session").text("Working");
$(".button").text("Stop");
}
else {
console.log("stopped");
state = "off";
minutes = workTime;
seconds = 0;
//clear counter
clearInterval(counterId);
clockDisplay.innerHTML = workTime +":00";
$(".button").text("Start");
}
});
//add work time
$('.plusWork').click(function() {
workTime++;
minutes = workTime;
$('.work').text(workTime);
clockDisplay.innerHTML = workTime +":00";
console.log(workTime);
});
//substract work time
$('.minWork').click(function() {
workTime--;
minutes = workTime;
$('.work').text(workTime);
clockDisplay.innerHTML = workTime +":00";
console.log(workTime);
});
//add break time
$('.plusBreak').click(function() {
breakTime++;
minutes = breakTime;
$('.break').text(breakTime);
console.log(breakTime);
});
//substract break time
$('.minBreak').click(function() {
breakTime--;
minutes = breakTime;
$('.break').text(breakTime);
console.log(breakTime);
});
//work countdown timer function
function countDown() {
//if workTime = 0 reset counter and stop
if(minutes == 0 && seconds == 0 && state == "on") {
clearTimeout(counterId);
//if work countdown reach 0, start break
minutes = breakTime;
seconds = 00;
setInterval(countDown, 1000);
return;
}
else if(minutes == 0 && seconds > 0) {
seconds--;
if(seconds < 10) seconds = "0"+seconds;
clockDisplay.innerHTML = minutes + ":" + seconds;
console.log(minutes +":"+seconds +" 2");
}
//when seconds < 0 substract a minute
else if(minutes > 0 && seconds < 0) {
minutes--;
seconds = 59;
clockDisplay.innerHTML = minutes + ":" + seconds;
console.log(minutes +":"+seconds +" 3");
}
else {
//if second single digit add 0
if (seconds < 10) seconds = "0"+seconds;
clockDisplay.innerHTML = minutes +":"+ seconds;
seconds--;
console.log(minutes +":"+seconds +" 4");
}
}
});

JS Timer, clearInterval() doesn't clear the timer. When restart, it resumes instead of restarting at zero

Well the title already says it. I am working on a timer, but when I let it run for around 10 secs, press space (space = keycode 13), then it stops and then if I press space again to start, it resumes but then +2 secondes. (started at e.g. 18 sec and resumes from 20 sec) which comes from the clearInterval ID it return I think... not sure.
If you guys could help me out, that'd be great.
If you have any suggesstions to do things differently, let me know too!
I'm open for all the feedback I get and improvement / tips on my code! :)
Javascript
var Timer = function() {
var self = this,
div = document.querySelector('.timer'),
hours, minutes, seconds, millsecs;
this.oldDate = new Date().getTime();
this.newDate;
this.isRunning = false;
this.time;
this.timerId = 0;
this.start = function() {
self.isRunning = true;
if (self.isRunning) {
self.timerId = setInterval(function() {
self.time = new Date().getTime() - self.oldDate;
self.time = self.time.toString();
millsecs= self.time.substr(-3);
seconds = (Math.floor(self.time / 1000) % 60) + '.';
minutes = (self.time >= 60000) ? (Math.floor(self.time / (1000*60)) % 60) + ':' : '';
hours = (self.time >= 86400) ? (Math.floor(self.time / (1000*60*60)) % 24) + ':' : '';
div.innerHTML = hours + minutes + seconds + millsecs;
}, 10);
}
}
this.stop = function() {
self.isRunning = false;
clearInterval(obj.timerId);
self.timerId = 0;
}
};
var obj = new Timer();
window.addEventListener('keyup', function(e) {
if(e.keyCode == 32 && obj.isRunning == false) {
obj.start();
}
else if (e.keyCode == 32 && obj.isRunning == true) {
obj.stop();
}
});

Counting up and down to specified number in order in Javascript

I am trying to get this script to count up to a specified number and back down to a specified number as follows: 19200, 38400, 57600, 76800, 96000, 76800, 57600, 38400, 19200 — repeatedly. So far this is what I have but I cannot seem to make it count down in the order above, it restarts from 19200 again.
$(function() {
var seconds = 19200;
var timerId = setInterval(function() {
seconds = seconds + 19200;
$("#counter").text(seconds);
if (seconds > "76800") {
clearInterval(seconds);
seconds = seconds - "19200";
}
}, 500);
});
A little issue with the logic, the condition
if (seconds > "76800") {
would always try to keep the seconds above 76800.
Rather you would want a flag to track the direction of the count. Check out below:
UPDATED:
Working demo at
JSFiddle
$(function () {
var increment = 19200;
var seconds = increment;
var countUp = true;
var timerId = setInterval(function () {
$("#counter").text(seconds);
if (countUp) {
seconds += increment;
} else {
seconds -= increment;
}
if (countUp && seconds > increment*4) {
countUp = false;
} else if (!countUp && seconds <= increment) {
countUp = true;
}
}, 500);
});
Check the below function
$(function() {
var seconds = 19200;
action = 'add';
var timerId = setInterval(function() {
$("#counter").text(seconds);
if (seconds == 96000) {
action = 'remove';
} else if (seconds == 19200) {
action = 'add'
}
if (action == 'add')
seconds += 19200;
else if (action == 'remove')
seconds -= 19200;
}, 500);
});
I think this is a little more elegant
var increment = 19200,
seconds = increment;
var timer = setInterval(function() {
console.log(seconds);
seconds += increment;
if (seconds > 76800 || seconds < 19200) {
increment *= -1;
}
}, 500);
jsfiddle

Categories