I have 1 counter. The counter will count down from 25 first. It will then start counting down from 10 when this time is up. When this time is over, it will start counting down from 25 again. That's how it will go. How can I do it?
var interval10 = 10000;
var interval = 25000;
function tensecond() {
var remaining = interval10 - (Date.now() % interval10);
}
setInterval(function () {
if (remaining >= 100) {
document.getElementById("timer").innerText =
millisToMinutesAndSeconds(remaining);
} else {
reset();
}
}, 100);
function reset() {
var remaining = interval - (Date.now() % interval);
}
setInterval(function () {
if (remaining >= 100) {
document.getElementById("timer").innerText =
millisToMinutesAndSeconds(remaining);
} else {
tensecond();
}
}, 100);
function millisToMinutesAndSeconds(millis) {
var seconds = Math.floor((millis % 60000) / 1000);
return (seconds < 10 ? "0" : "") + seconds;
}
I'm not entirely sure what you were trying to do in your code. It's easier if you run one interval every second and keep track of which counter you're in and how much time there's left. Like this:
let timeLeft = 25;
let counter = false; // false = 25 sec counter, true = 10 sec counter
setInterval(() => {
if (timeLeft !== 0) return timeLeft--;
if (!counter) {
timeLeft = 10;
counter = true;
// do some more stuff
} else {
timeLeft = 25;
counter = false;
// do some more stuff
}
}, 1000);
Perhaps you had in mind such an implementation?
Each task triggers the following
const interval10 = 1000;
const interval = 2500;
let remaining;
function print(rem, type) {
if (remaining >= rem) {
document.getElementById("timer").innerText =
millisToMinutesAndSeconds(remaining);
} else {
if (type === '25') {
reset()
} else {
tensecond()
}
}
}
function tensecond() {
remaining = interval10 - (Date.now() % interval10);
}
function run25() {
setTimeout(function () {
print(100, '25')
run10()
}, interval);
}
function run10() {
setTimeout(function () {
print(100, '10')
run25()
}, interval10);
}
function reset() {
remaining = interval - (Date.now() % interval);
}
function millisToMinutesAndSeconds(millis) {
const seconds = Math.floor((millis % 60000) / 1000);
return (seconds < 10 ? "0" : "") + seconds;
}
run25();
delete code duplication
The best way to deal with this is to use promises. Each countdown is a promise which resolves once the timer is expired. This way you can chain any number of timers.
SPEED = 100 // set to 1000 to use seconds
function timer(secs, target) {
let endTime = Number(new Date()) + (secs + 1) * SPEED
return new Promise(resolve => {
function step() {
let now = Number(new Date())
if (now >= endTime) {
target.innerText = '0'
return resolve()
}
target.innerText = Math.floor((endTime - now) / SPEED)
window.requestAnimationFrame(step)
}
step()
})
}
async function loop() {
while (1) {
await timer(30, document.querySelector('#a'))
await timer(20, document.querySelector('#b'))
await timer(10, document.querySelector('#c'))
}
}
window.onload = loop
<body style="font-size: 30px">
<div id="a"></div>
<div id="b"></div>
<div id="c"></div>
</body>
Related
Beginner JS project, got everything to work but I wanted to play around with colors. Looking to get the timer to change colors every 10 seconds. I thought a basic function would work but apparently not. I know I'm doing something wrong somewhere but I cant figure it out.
window.onload = function () {
let seconds = 00;
let tens = 00;
const roundTens = $("#tens");
const roundSeconds = $("#seconds");
const buttonStart = document.getElementById("button-start");
const buttonStop = document.getElementById("button-stop");
const buttonReset = document.getElementById("button-reset");
let Interval;
buttonStart.onclick = function () {
clearInterval(Interval);
Interval = setInterval(startTimer, 10);
};
buttonStop.onclick = function () {
clearInterval(Interval);
};
buttonReset.onclick = function () {
clearInterval(Interval);
tens = "00";
seconds = "00";
roundTens.text(tens);
roundSeconds.text(seconds);
};
function colorChange(color1, color2) {
if (color1.value === "00" && color2.value === "59") {
color1.style.color = "orange";
color2.style.color = "red";
} else if (color1.value === "00" && color2s.value === "00") {
color1.style.color = "green";
color2.style.color = "blue";
}
}
function startTimer() {
tens++;
if (tens <= 9) {
roundTens.text("0" + tens);
}
if (tens > 9) {
roundTens.text(tens);
}
if (tens > 99) {
console.log("seconds");
seconds++;
roundSeconds.text("0" + seconds);
tens = 0;
roundTens.text("0" + tens);
}
if (seconds > 9) {
roundSeconds.text(seconds);
}
}
colorChange();
};
startTimer should call colorChange (currently never called)
<script>
var minutes = 1;
var seconds = 45;
$(document).ready(function () {
setInterval(startTimer, 1000);
});
function startTimer() {
document.getElementById("timer").innerHTML = (minutes - 1) + ":" + --seconds;
if (seconds == 0) {
minutes--;
if (minutes != 0) {
seconds = 60;
} else {
seconds = 0;
}
}
if (minutes == 0 && seconds == 0) {
document.getElementById('next').click();
minutes = 1;
seconds = 45;
}
}
</script>
This is my code for the timer and it should restart after button click whose id is #next. I did many things but it won't work. Please help.
Button Id = Next
Here's my solution to your issue.
I've noticed $(document).ready() so I instantly presumed you are
using jQuery.
var timerInterval is a direct reference to the timer that you started.
To stop the timer, use clearInterval(timerInterval) [Same story goes for setTimeout()].
I've changed your countdown timer because I couldn't be bothered fixing it.
var timerInterval;
let minutes = 2;
let seconds = 42;
let duration = (minutes * 60) + seconds;
let display = document.querySelector('#timer');
function startTimer(duration, display) {
var timer = duration, minutes, seconds;
timerInterval = 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 = minutes + ":" + seconds;
if (--timer < 0) {
timer = duration;
clearInterval(timerInterval);
}
}, 1000);
}
startTimer(duration, display);
$('button').click((e) => {
clearInterval(timerInterval);
startTimer(duration, display);
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<span id="timer"></span>
<br>
<button>Reset Timer</button>
You should not rely on setInterval (or setTimeout) to calculate a time value. It is not guaranted to be called at the specified interval. I believe in some case it could also be paused by the browser.
You could try something like this :
<span id='timer'></span>
<button id='next'>Next</button>
<script>
var btn = document.getElementById('next');
btn.addEventListener('click', function(e) {
// 10 is the duration in seconds
startNextTimer(10, function() { alert('done!');} );
});
function startNextTimer(numSecondsDuration, callback) {
var label = document.getElementById('timer');
var endDate = new Date();
endDate.setSeconds(endDate.getSeconds() + numSecondsDuration);
var calcTimeLeft = function() { return Math.ceil((endDate - (new Date())) / 1000); };
label.innerHTML = calcTimeLeft() + " secs";
var intervalId = setInterval(function() {
var numSecondsLeft = calcTimeLeft();
if (numSecondsLeft <= 0) {
clearInterval(intervalId);
if (callback) {
callback();
}
}
label.innerHTML = numSecondsLeft + " secs";
}, 500);
}
</script>
Without the html I can't give you step by step but basically, you need to clear the interval before you can restart it.
<script>
var minutes = 1;
var seconds = 45;
var interval_id=setInterval(startTimer, 1000);
$('#next').on("click",function(){
clearInterval(interval_id);
minutes = 1;
seconds = 45;
document.getElementById("timer").innerHTML ="";
interval_id=setInterval(startTimer, 1000);
});
function startTimer() {
document.getElementById("timer").innerHTML = (minutes - 1) + ":" + --seconds;
if (seconds == 0) {
minutes--;
if (minutes != 0) {
seconds = 60;
} else {
seconds = 0;
}
}
if (minutes == 0 && seconds == 0) {
minutes = 1;
seconds = 45;
}
}
</script>
I have created a countdown timer and am trying to add 2 minutes into the existing timer to extend the timer.
My Code
function CountDownTimer(duration, granularity) {
this.duration = duration;
this.granularity = granularity || 1000;
this.tickFtns = [];
this.running = false;
}
CountDownTimer.prototype.start = function() {
if (this.running) {
return;
}
this.running = true;
var start = Date.now(),
that = this,
diff, obj;
(function timer() {
diff = that.duration - (((Date.now() - start) / 1000) | 0);
if (diff > 0) {
setTimeout(timer, that.granularity);
} else {
diff = 0;
that.running = false;
}
obj = CountDownTimer.parse(diff);
that.tickFtns.forEach(function(ftn) {
ftn.call(this, obj.minutes, obj.seconds);
}, that);
}());
};
CountDownTimer.prototype.onTick = function(ftn) {
if (typeof ftn === 'function') {
this.tickFtns.push(ftn);
}
return this;
};
CountDownTimer.prototype.expired = function() {
return !this.running;
};
CountDownTimer.parse = function(seconds) {
return {
'minutes': (seconds / 60) | 0,
'seconds': (seconds % 60) | 0
};
};
$(document).ready(function() {
var counter = 0;
var display = document.querySelector('#time'),
//timer = new CountDownTimer(600);
timer = new CountDownTimer(125); // for debug
timer.onTick(format).onTick(restart).start();
function restart() {
if (this.expired()) {
alert("Expired");
}
}
function format(minutes, seconds) {
minutes = minutes < 10 ? "0" + minutes : minutes;
seconds = seconds < 10 ? "0" + seconds : seconds;
display.textContent = minutes + ':' + seconds;
if (minutes < 2) {
if (counter == 0) {
alert("Extending Time");
counter++;
}
}
}
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<span id="time"></span> minutes
I managed to trigger an event that after 2 minutes will show an alert that the time will be extended, but so far, I can't think of any method or functions I can use to add the extra time. Is there any way I can do this?
Add code as following:
CountDownTimer.prototype.reset = function (duration) {
this.duration = duration;
}
and rewrite function format as :
function format(minutes, seconds) {
minutes = minutes < 10 ? "0" + minutes : minutes;
seconds = seconds < 10 ? "0" + seconds : seconds;
display.textContent = minutes + ':' + seconds;
if (minutes < 2) {
if (counter == 0) {
//alert("Extending Time");
timer.reset(timer.duration + 120);
counter++;
}
}
}
You can add code in CountDownTimer.prototype.start before setTimeout like:
this.instance = setTimeout(...)
add function:
CountDownTimer.prototype.kill = function() {
clearTimeout(this.instance)
}
call function kill to stop timer permanently.
Session length is the start time of the timer, default is 25. isEven is used to start/stop the timer, if isEven is false, the timer should start, if it is odd it should hit clearInterval, which for some reason is not stopping execution of tick() function (which counts down the timer).
var count = 0;
function countdown(sessionLength) {
var minutes = sessionLength - 1;
var seconds = 60;
var isEven = false;
count++;
if (count % 2 == 0) {
isEven = true;
} else {
isEven = false;
}
var myVar = setInterval(tick, 1000);
if (isEven == false) {
function tick() {
if (seconds > 0) {
seconds--;
} else {
minutes--;
seconds = 59;
}
if (minutes > 0) {
document.getElementById("time").innerHTML =
minutes.toString() + ":" + (seconds < 10 ? "0" : "") + seconds.toString();
} else {
document.getElementById("time").innerHTML =
"0:" + (seconds < 10 ? "0" : "") + seconds.toString();
}
}
} else {
console.log("reached");
clearInterval(myVar);
}
};
Move the tick() function declaration outside of the if block
setInterval variable is a local one. So its value is overwritten every time you call countdown
. The solution would be to initialize myVar outside the function countdown or to make it a global variable like this :
window.myVar =setInterval (tick,1000);
You have also to put this instruction in the first if block, so that it is not overwritten everytime
var count = 0;
function countdown(sessionLength) {
var minutes = sessionLength - 1;
var seconds = 60;
var isEven = false;
count++;
if (count % 2 == 0) {
isEven = true;
} else {
isEven = false;
}
if (isEven == false) {
window.myVar = setInterval(tick, 1000);
function tick() {
if (seconds > 0) {
seconds--;
} else {
minutes--; seconds = 59;
}
if (minutes > 0) {
document.getElementById("time").innerHTML = minutes.toString() + ":" + (seconds < 10 ? "0" : "") + seconds.toString();
} else {
document.getElementById("time").innerHTML = "0:" + (seconds < 10 ? "0" : "") + seconds.toString();
}
}
} else {
console.log("reached");
if (window.myVar){
clearInterval(window.myVar);
window.myVar = null;
}
}
};
I'm creating java script count down timer and it works up to 60 seconds correctly and after that its not working.
var counter = setInterval(timer, 1000); //1000 will run it every 1 second
function timer() {
var val = document.getElementById("LabelTimer");
if (val != null) {
var PopUpTimeDuration = 2;
countdown(parseInt(PopUpTimeDuration));
}
}
function countdown(minutes) {
var seconds = 60;
var mins = minutes
function tick() {
var counterVal = document.getElementById("lblCountDown");
var current_minutes = mins - 1
seconds--;
counterVal.innerHTML =
current_minutes.toString() + ":" + (seconds < 10 ? "0" : "") + String(seconds);
var result = counterVal.innerHTML;
if (result == "0:00") {
clearInterval(counter);
CloseIdlePage();
}
if (seconds > 0) {
setTimeout(tick, 1000);
} else {
debugger;
if (mins >= 1) {
countdown(mins - 1);
}
}
}
tick();
}
When i run this program this start 1:59 and it continues up to 1:01. after that this display value rest to 1:59. (not 0:59). what i did wrong in here?
Fiddle demo is in Here: in here you can see two values are blinking each other
Here's how I'd implement this. Hopefully the comments are sufficient. It needs an element in the page with ID "counterDiv" to write the values to.
function quickCount(mins) {
// Keep some values in a closure
var el = document.getElementById('counterDiv');
var secs = 0;
// Helper to pad single digit numbers
function z(n){return (n<10? '0':'') + n}
// Keep a reference to the interval
var timer = setInterval(function() {
// Write the values
el.innerHTML = mins + ':' + z(secs);
// Decremement seconds
--secs;
// If finished a minute, decrement minut
if (secs < 0) {
if (mins) {
--mins;
secs = 59;
// If finsihed minutes too, cancel timer
} else {
timer && clearInterval(timer);
}
}
// Run at about every second
}, 1000);
}
window.onload = function() {
quickCount(2);
}
HTH
<head>
<script type="text/javascript">
function timer()
{
var val = document.getElementById("LabelTimer");
if (val !== null)
{
var PopUpTimeDuration = 2;
countdown(parseInt(PopUpTimeDuration));
}
}
function countdown(minutes)
{
var seconds = 60;
var mins = minutes;
function tick()
{
var counterVal = document.getElementById("lblCountDown");
var current_minutes = mins - 1;
seconds--;
var t=current_minutes.toString() + ":" + (seconds < 10 ? "0" : "") + String(seconds);
counterVal.value = t;
var result = counterVal.innerHTML;
if (result === "0:00")
{
CloseIdlePage();
}
if (seconds > 0)
{
setTimeout(tick, 1000);
}
else
{
if (mins > 1)
{
countdown(mins - 1);
}
}
}
tick();
}
</script>
</head>
<body>
<div>TODO write content</div>
<input type="text" id="LabelTimer" value="yooo">
<input type="text" id="lblCountDown">
<input type="button" value="try" onclick="timer();" />
</body>
I resolved this as follows:
var counter = setInterval(timer, 1000); //1000 will run it every 1 second
var IsFunctionCalled = false;
function timer() {
var val = document.getElementById("LabelTimer");
if (val != null) {
var PopUpTimeDuration = 2;
if (IsFunctionCalled == false) {
IsFunctionCalled = true
countdown(parseInt(PopUpTimeDuration));
}
}
}
function countdown(minutes) {
var seconds = 60;
var mins = minutes
function tick() {
var counterVal = document.getElementById("lblCountDown");
var current_minutes = mins - 1
seconds--;
counterVal.innerHTML =
current_minutes.toString() + ":" + (seconds < 10 ? "0" : "") + String(seconds);
var result = counterVal.innerHTML;
if (result == "0:00") {
clearInterval(counter);
CloseIdlePage();
}
if (seconds > 0) {
setTimeout(tick, 1000);
// tick()
} else {
if (mins >= 1) {
countdown(mins - 1);
}
}
}
tick();
}
See here for Demo