setTimeout not working, and yes the function does not have () - javascript

I am making a timer and for some reason the timer is not properly decrementing using the countDown function in the code below. I am using setTimeout to call it countDown repeatedly but when I checked the debugger JavaScript does not even go to that line, after the second-to-last line timeEl.textContent = tempMinutes + ":" + tempSeconds; it just stops. I tried setInterval but its the same.
I want to know how to have the timer go down and setTimeout to do its thing, but how? Any advice or help is greatly appreciated!
const workBtnEl = document.querySelector("#work-btn");
const shortBreakBtnEl = document.querySelector("#short-break-btn");
const longBreakBtnEl = document.querySelector("#long-break-btn");
let timeEl = document.querySelector("#time");
const work = 25;
const shortBreak = 5;
const longBreak = 15;
let currentMinutes, currentSeconds = 0;
workBtnEl.addEventListener("click", function() {
timeEl.textContent = "25:00";
currentMinutes = work;
countDown(currentMinutes, 0);
});
function countDown(minutes, seconds) {
if (seconds == 0) {
if (minutes == 0) {
return;
}
minutes -= 1;
seconds = 59;
}
let tempSeconds = seconds;
let tempMinutes = minutes;
if (seconds < 10) {
tempSeconds = "0" + seconds;
}
if (minutes < 10) {
tempMinutes = "0" + minutes
}
timeEl.textContent = tempMinutes + ":" + tempSeconds;
let time = setTimeout(countDown, 1000, minutes, seconds);
}
<button id="work-btn">
Work
</button>
<button id="short-break-btn">
Short break
</button>
<button id="long-break-btn">
Long break
</button>
<span id="time">Time</span>

You never decrease seconds when it is non-zero.
So add that after the if block:
if (seconds == 0) {
// your code...
} else seconds--; // <---

You need to reduce the seconds variable in the countDown function otherwise the same text will be printed to your text area each time.
Right now you just have a condition if the seconds are 0 then set seconds to 59.

See what you have done in this line :
let currentMinutes, currentSeconds = 0;
currentMinutes will be undefined mostly, I used Node REPL to check
If you have something like :
let a, b = 0
The value of a was undefined & b got set to zero
An appropriate assignment would be
let currentMinutes = 0;
let currentSeconds = 0;

Related

how to prevent a condition when setInterval is running

I've watched many tutorials with alarm clocks and created my own but I'm still learning JS and I can't pause the sound because setInterval in the clock is running. pause() doesn't work because in a second the alarm is still going off. Can anyone help me?
let now;
let hours;
let minutes;
let seconds;
function clock() {
now = new Date();
hours = now.getHours();
minutes = now.getMinutes();
seconds = now.getSeconds();
// add zero for the values lower than 10
if (hours < 10) {
hours = "0" + hours;
}
if (minutes < 10) {
minutes = "0" + minutes;
}
if (seconds < 10) {
seconds = "0" + seconds;
}
document.querySelector(".hours").innerHTML = hours;
document.querySelector(".minutes").innerHTML = minutes;
document.querySelector(".seconds").innerHTML = seconds;
console.log(`${hours}:${minutes}`);
// ##### this is the part sounds the alarm #####
if (alarmTime == `${hours}:${minutes}`) {
console.log(`Alarm ringing...`);
ringtone.play();
ringtone.loop = true;
}
}
let updateClock = setInterval(clock, 1000);
let alarmTime;
let ringtone;
ringtone = new Audio("./files/alarm.wav");
function setAlarm() {
let time = `${selectMenu[0].value}:${selectMenu[1].value}`;
alarmTime = time;
content.classList.add("disable");
setAlarmBtn.innerText = "alarm is set";
console.log(alarmTime);
}
setAlarmBtn.addEventListener("click", setAlarm);
// ##### This is one of some attempts to stop it
function stop() {
ringtone.pause();
ringtone.loop = false;
}
<button class="alarm-clock-button">set alarm</button>
<button class="alarm-off-button" onclick="stop()">alarm off</button>
I don't want to copy the whole code because it is quite bulky.
If you want to disable the setInterval entirely, use clearInterval(updateClock), if you don't want to disable it then you can put a boolean variable isPaused and check for it when alarmTime is being checked, you can use isPaused = !isPaused in your stop function to toggle it or just use false
Code Example:
let isPaused = false; //declaration
if (alarmTime == `${hours}:${minutes}` && !isPaused) { // this will replace the condition!
console.log(`Alarm ringing...`);
ringtone.play();
ringtone.loop = true;
}
function setAlarm() {
let time = `${selectMenu[0].value}:${selectMenu[1].value}`;
alarmTime = time;
content.classList.add("disable");
setAlarmBtn.innerText = "alarm is set";
console.log(alarmTime);
isPaused = false; // If it's being reset for whatever reason
}
function stop() { // this will replace your stop function
ringtone.pause();
ringtone.loop = false;
isPaused = true;
}

Timer reaching zero then calling a function fail

I have taken this simple timer method from here.
What I want is pretty simple, yet I can’t figure it out.
When the timer reaches zero (0:00), I want a popup alert. At the same time, the timer should continue in negative time.
So everything is working, except the popup. Any idea why?
window.onload = function() {
var minute = 0;
var sec = 3;
setInterval(function() {
document.getElementById("timer").innerHTML = minute + " : " + sec;
sec--;
if (sec == 00) {
minute --;
sec = 59;
if (minute == 0 && sec == 00) {
alert("You failed!");
}
}
}, 1000);
}
<div class="countdown" class="failed" id="coutdown">
Time remaining to find solution: <span id="timer">10 : 00</span>
</div>
window.onload = function() {
var minute = 0;
var sec = 3;
var timer = document.getElementById("timer");
setInterval(function() {
if (sec === 0) {
timer.innerHTML = minute + " : " + sec;
if (minute === 0 && sec === 0) {
alert("You failed!");
}
minute--;
sec = 60;
} else {
timer.innerHTML = minute + " : " + sec;
}
sec--;
}, 1000);
}
<div class="countdown" class="failed" id="coutdown">
Time remaining to find solution: <span id="timer">10 : 00</span>
</div>
You are checking minute and second conditions after minute-- in your code, which means -1 is not equal to zero. Write an if condition before making minus 1 in your code.
Please use console.log("You failed!") instead of alert("You failed!") to ensure an accurate result.
Your conditional is checking whether sec == 0 immediately after you set sec = 59, so the conditional will never occur. Do you mean to have the order of this setter and the conditional swapped?
This is what I mean by restructuring the code entirely into reusable functions. comment what you don't understand and I will explain. I try not to hard code anything timer fetches its starter value from HTML.
const display = document.getElementById("timer");
function toArray(domEl){
return domEl.innerHTML.split(':').map(el => +el);
}
function getSec(timeArr){
if(timeArr.length > 3 || timeArr.length === 0) return;
return timeArr.reverse().map((el, i) => el * 60 ** i).reduce((cur,accu)=> cur + accu);
}
let totalSec = getSec(toArray(display))
setInterval(()=>{
totalSec--;
display.textContent = formatTime(totalSec);
},1000)
function formatTime(sec){
const time = {hr:0, min:0, sec:0};
time.hr = ~~(sec/3600) || 0;
time.min = ~~(~~(sec%3600)/60);
time.sec = ~~(sec%3600)%60;
if(time.hr===0 && time.min===0 && time.sec ===0) alert("You Faild!")
return `${time.hr ? time.hr + ':':''}${padTime(time.min)}:${padTime(time.sec)}`
}
function padTime(time){
return time? String(time).padStart(2,0):0;
}
<div class="countdown" class="failed" id="coutdown">
Time remaining to find solution: <span id="timer">0:01:05</span>
</div>

How to stop timer count and start with saved time

I'm kinda new to programming, but recently I was trying to do little first project of mine called timer count, it's just simple local website which I open when I'm deciding to start programming during the day and it counts the time. I created 2 buttons with 2 different functions (start,stop), but the problem I'm stuck on is I don't know how to implement stop function. The idea is that timer should stop after button click, and when I click start button it should start from saved time.
Here's HTML/CSS code:
<div class="timer-display-id">
<h1>Timer </h1>
<p id="timer">00:00:00 </p>
<button id="start-timer" onclick="start()">Start </button>
<button id="stop-timer" onclick="stop()">Stop </button>
</div>
<script src="timer.js"></script>
and here's JS code:
function stop() {
// not exactly sure if this function should be here, anyway no idea what to add to get this to work
clearInterval(interval);
start.disabled = false;
}
function convertSec(cnt) {
let sec = cnt % 60;
let min = Math.floor(cnt / 60);
if (sec < 10) {
if (min < 10) {return "0" + min + ":0" + sec;}
else {return min + ":0" + sec;}
}
else if ((min < 10) && (sec >= 10)) {return "0" + min + ":" + sec;}
else {return min + ":" + sec;}
}
function start() {
let ret = document.getElementById("timer");
let counter = 0;
let start = document.querySelector("#start-timer");
let stop = document.querySelector("#stop-timer");
start.disabled = true;
let interval = setInterval(function() {
ret.innerHTML = convertSec(counter++); // timer start counting here...
},1000);
}
I understand it might be very messy, kinda lack of logic, but it's best I can do for now. If you'd like to give some tips about code organizing, I'd appreciate it.
You nee to have interval accessible by both functions whileit holds the setInterval function, just move it outside the start function :
const ret = document.getElementById("timer");
const startBtn = document.querySelector("#start-timer");
let counter = 0;
let interval;
function stop() {
clearInterval(interval);
startBtn.disabled = false;
}
function convertSec(cnt) {
let sec = cnt % 60;
let min = Math.floor(cnt / 60);
if (sec < 10) {
if (min < 10) {
return "0" + min + ":0" + sec;
} else {
return min + ":0" + sec;
}
} else if ((min < 10) && (sec >= 10)) {
return "0" + min + ":" + sec;
} else {
return min + ":" + sec;
}
}
function start() {
startBtn.disabled = true;
interval = setInterval(function() {
ret.innerHTML = convertSec(counter++); // timer start counting here...
}, 1000);
}
<div class="timer-display-id">
<h1>Timer </h1>
<p id="timer">00:00:00 </p>
<button id="start-timer" onclick="start()">Start </button>
<button id="stop-timer" onclick="stop()">Stop </button>
</div>
If you want the count to be saved after you hit "stop", and to re-start from the same point, you will need to define your count variable somewhere outside the start() function, so that it can tell what count to restart from. At the moment, count is local to the start() function, which will reset it to zero every time.
By using the 1s interval timer to update the count, your counter will round each period to whole seconds. It would be slightly more complicated, but if you want to be able to add up the partial seconds from multiple counts, it would be more accurate to use something like Date.getTime() to record the time the start button is pressed, then check the elapsed time when stop() is triggered, and add that to your count. You might still want to use an interval timer to regularly update the current value though. Again, you would need to check that the variables you want to use have the correct scope, so that they are visible to the functions that use them, and not lost between function calls.

CountDown Script, Doesn't display or countdown correctly

so I've been tyring to debug my script for my pomodoro(tomato) clock. What I want this script to do is it will recieve input(in minutes). Right now what my script is doing is counting down by 5 instead of 1 seconds. Also it will not display the minutes like I want it too.
I made the script in a logical way to log to console and test it. What I see in the console is it displays every second, but it displays 5 seconds every second if that makes sense. Here is the jsbin: https://jsbin.com/gigohajawo/3/edit?js,consolehttps://jsbin.com/gigohajawo/3/edit?js,console
Here is the code, any help would be appreciated!!!
//makes sure the page is loaded first
$(document).ready(function() {
//global variables
//grabs text of an id and converts it to an int
var countMin = 5;
var count1 = 60;
//when button id "but" is clicked...
//while page is up, it keeps track each second that has passed
for(; countMin >=0;countMin--){
var counter1 = setInterval(function(){
//calls timer function to count down
count1 = Timer(count1,counter1,countMin);
},1000);
count1 =60;
}
//counts down
function Timer(count,counter,minutes){
count--;
//once it hits 0 seconds, the interval will stop counting
if(count <=0){
clearInterval(counter);
return count;
}
//displays the countdown
if(minutes < 10){
if(count < 10){
console.log("0:0" + count);
} else {
console.log("0:" + count);
}
}else if(minutes > 0 && minutes < 10){
if(count < 10){
console.log("0" + minutes +":0" + count);
} else {
console.log("0"+minutes+":" + count);
}
} else{
if(count < 10){
console.log(minutes+":0" + count);
} else {
console.log=minutes+":" + count;
}
}
return count;
}
});
This JSBin seems to do what you intended.
The code:
//makes sure the page is loaded first
$(document).ready(function() {
//global variables
//grabs text of an id and converts it to an int
var count1 = 120;
// Call a function every 1000 milliseconds (1 second)
var counter1 = setInterval(function() {
count1 = Timer(count1, counter1);
}, 1000);
//counts down
function Timer(count,counter){
// Decrement the seconds counter
count--;
// Get the minutes and seconds in whole numbers
var minutes = Math.floor(count / 60);
var seconds = count % 60;
// Once it hits 0 seconds, the interval will stop counting
if(count <=0){
clearInterval(counter);
}
// Pads the seconds with a 0
if (seconds < 10) {
seconds = "0" + seconds;
}
// Pads the minutes with a 0
if (minutes < 10) {
minutes = "0" + minutes;
}
//displays the countdown
console.log(minutes + ":" + seconds)
return count;
}
});
Please note:
Since you have defined count1 as a global variable you do not need to pass it into Timer
The same goes for counter1
If I was rewriting it I would do something like this:
//makes sure the page is loaded first
$(document).ready(function() {
var timeInSeconds = 120;
var timeCounter = setInterval(function() {
timeInSeconds--;
// If we hit 0 seconds clear the timer
if (timeInSeconds <= 0) {
clearInterval(timeCounter);
}
// Display the current time
displayTime();
}, 1000);
function displayTime(){
// Get the minutes and seconds in whole numbers
var minutes = Math.floor(timeInSeconds / 60);
var seconds = timeInSeconds % 60;
// Pad with zeros using the Ternary operator
seconds = (seconds < 10) ? "0" + seconds : seconds;
minutes = (minutes < 10) ? "0" + minutes : minutes;
// Display the countdown
console.log(minutes + ":" + seconds)
}
});

How do you decrement time for minutes seconds hundredths?

Suppose you wanted to set a timer to whatever time you want will be displayed in the form 00:00:00 minutes, seconds, and hundredths. How would you go about doing so? Please any help is greatly appreciated.
Here is the link in JSFiddle:
https://jsfiddle.net/mxpuejvz/2/
function decrement(){
var time = 600;
var mins = parseInt((time / 100) / 60);
var secs = parseInt((time / 100) % 60);
var hundredths = parseInt(time % 100);
if(mins < 10) {
mins = "0" + mins;
}
if(secs < 10) {
secs = "0" + secs;
}
if(hundredths < 10) {
hundredths = "0" + hundredths;
}
document.getElementById("output").innerHTML = mins + ":" + secs + ":" + hundredths;
if (hundredths === 0){
if(time ===0){
clearInterval(countdownTimer);
document.getElementById("output").innerHTML = "Time's Up.";
}else{
time--;
}
var countdownTimer = setInterval('decrement()', 10)
}
}
}
Three issues appear to need attention.
"time to go" needs to be stored outside the screen update function and decremented or calculated each time the screen is updated.
using parseInt to convert numbers to integer numbers is regarded as a hack by some. Math.floor() or integer calculation can be alternatives.
Timer call backs are not guaranteed to made exactly on time: counting the number of call backs for a 10msec time does not give the number of 1/100ths of elapsed time.
The following code is an example of how it could work, minus any pause button action.
var countdownTimer;
var endTime;
var counter = 0; // ** see reply item 3. **
function startCountDown( csecs) // hundredths of a second
{ endTime = Date.now() + 10*csecs; // endTime in millisecs
decrement();
countdownTimer = setInterval(decrement, 10);
counter = 0; // testing
}
function decrement()
{ var now, time, mins, secs, csecs, timeStr;
++ counter; // testing
now = Date.now();
if( now >= endTime)
{ time = 0;
timeStr = "Times up! counter = " + counter;
clearInterval( countdownTimer);
}
else
{ time = Math.floor( (endTime - now)/10); // unit = 1/100 sec
csecs = time%100;
time = (time-csecs)/100; // unit = 1 sec
secs = time % 60;
mins = (time-secs)/60; // unit = 60 secs
timeStr =
( (mins < 10) ? "0" + mins : mins) + ":" +
( (secs < 10) ? "0" + secs : secs) + ":" +
( (csecs < 10) ? "0" + csecs : csecs);
}
document.getElementById("output").innerHTML=timeStr;
}
The argument to startCountDown gives the number of 1/100ths of second for the count down. If the counter result is the same as the argument,try swapping browser tabs and back again during the countdown.
HTML to test:
<button type="button" onclick="startCountDown(600)">start</button>
<div id="output">
</div>

Categories

Resources