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;
}
Related
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;
I need help or idea for use a countdown inside a setInterval.
heres my countdown timer on js (pretty obvious):
function startTimer(duration) {
var timer = duration, minutes, seconds;
setInterval(function () {
minutes = parseInt(timer / 60, 10);
seconds = parseInt(timer % 60, 10);
minutes = minutes < 10 ? "0" + minutes : minutes;
seconds = seconds < 10 ? "0" + seconds : seconds;
document.getElementById('minuteDrag').innerText = minutes;
document.getElementById('secondDrag').innerText = seconds;
if (--timer < 0) {
timer = duration;
}
}, 1000);
}
When i call this function outside the second setinterval, that works pecfectly (as expected).
But when i tried to run this function in the code below, the function for time countdown gets bugged, i guess it's because the countdown timer is called within another setinterval.
Any ideas for a solution here? (i can't get out the "main setinterval").
var api = new Lolesports_API();
api.get_event_details('pt-BR', '105562529627228920')
.then(result_games => {
var game_id
result_games.event.match.games.forEach(game => game_id = game.id)
api.get_teams('pt-BR')
.then(result_teams =>{
var teams_dict = {}
result_teams.teams.forEach(team => {teams_dict[team.id] = team.code})
setInterval(function(){
api.get_window(game_id, get_lastest_date())
.then(result_window => {
var last_frame = result_window.frames[result_window.frames.length - 1];
var game_state = last_frame.gameState;
startTimer(60*5)
if (game_state == 'in_game') {
document.getElementById("gameState").style.backgroundColor = '#33cc33';
stopwatch_game.start();
} else if (game_state == 'paused') {
document.getElementById("gameState").style.backgroundColor = '#66a3ff';
stopwatch_game.pause();
} else {
document.getElementById("gameState").style.backgroundColor = '#ff8080';
stopwatch_game.pause();
}
//stopwatch_game.start();
})
}, 500)
})
})
PS: this is not the full code, i remove a large part in order not to pollute the question.
Right now you're starting a new CountDown Interval every half second.
Why not return the value from the setInterval in startTimer so that it can be stopped as necessary by the outer loop?
e.g.
startTimer = (duration) => {
let timer = duration, minutes, seconds;
return setInterval(function () {
minutes = parseInt(timer / 60, 10);
seconds = parseInt(timer % 60, 10);
minutes = minutes < 10 ? "0" + minutes : minutes;
seconds = seconds < 10 ? "0" + seconds : seconds;
document.getElementById('minuteDrag').innerText = minutes;
document.getElementById('secondDrag').innerText = seconds;
if (--timer < 0) {
timer = duration;
}
}, 1000);
}
Then in your main loop you can use clearInterval to stop the timer... or at least check if it exists:
let foo = undefined;
if (foo === undefined) {
foo = startTimer(60*5);
}
Before asking the question I would like to inform you that I've already searched in the questions with related topics , but my issues are different from others. Actually, I am building a "Javascript stopwatch", but there are some issues in the script that I've tried and searched to solve but can't find none. There are there issues in the stopwatch:
The stopwatch restarts automatically when page reloads even though the timer was stopped by the "stop_btn".
The stopwatch restarts automatically with the time comparing starting time and present time when page reloads; the paused time is totally ignored !
Can the stopwatch be started from a specific dynamic value; something like PHP variable as:
$time = "01:06:39"; ?
The Javascript:
var timer;
var startTime;
var isRunning = false;
var waitedTime = 0;
var stoppedTime = 0;
function start() {
if (isRunning) return;
isRunning = true;
startTime = parseInt(localStorage.getItem('startTime') || Date.now());
if (timer) {
waitedTime += (Date.now() - stoppedTime);
}
localStorage.setItem('startTime', startTime);
timer = setInterval(clockTick, 100);
}
function stop() {
isRunning = false;
clearInterval(timer);
stoppedTime = Date.now();
}
function reset() {
isRunning = false;
stoppedTime = 0;
waitedTime = 0;
clearInterval(timer);
timer = undefined;
localStorage.removeItem('startTime');
document.getElementById('display-area').innerHTML = "00:00:00.000";
}
function clockTick() {
var currentTime = Date.now(),
timeElapsed = new Date(currentTime - startTime - waitedTime),
hours = timeElapsed.getUTCHours(),
mins = timeElapsed.getUTCMinutes(),
secs = timeElapsed.getUTCSeconds(),
ms = timeElapsed.getUTCMilliseconds(),
display = document.getElementById("display-area");
display.innerHTML =
(hours > 9 ? hours : "0" + hours) + ":" +
(mins > 9 ? mins : "0" + mins) + ":" +
(secs > 9 ? secs : "0" + secs) + "." +
(ms > 99 ? ms : ms > 9 ? "0" + ms : "00" + ms);
};
var stopBtn = document.getElementById('stop_btn');
var startBtn = document.getElementById('start_btn');
var resetBtn = document.getElementById('reset_btn');
stopBtn.addEventListener('click', function() {
stop();
});
startBtn.addEventListener('click', function() {
start();
});
resetBtn.addEventListener('click', function() {
reset();
})
start();
Can anyone help please ?
You can add this new variable and then use it in the start function. If the custom time is defined then localstorage or current date will be ignored.
var customStartTime = new Date() // enter your custom date in the Date() function.
Then modify the starttime in the start() function
startTime = customStartTime || parseInt(localStorage.getItem('startTime') || Date.now());
Have you considered using window.onload handler from which you can load stopwatch value after page reload, I think this should cover first 2 issues you mentioned.
Also when you reload page stoppedTime variable will be 0, use localStorage to cache stoppedTime.
I'm making a game that has a timer in it.
What I'm trying to do is -- when the game starts via gameState.init(), the timer starts through timer.counter("start") -- but when the "restart" button is clicked, the timer stops and resets through timer.counter("reset").
The timer does reset back to 0, but it keeps counting and not getting cleared.
Appreciate any insight I can get. Thanks in advance!
var gameState = {
init: function(){
var difficultyLevel = document.querySelector('input[name="level"]:checked').value;
conditions.difficulty(difficultyLevel);
startFrame.classList.remove("active");
shuffleCards();
timer.counter("start");
display.moves(movesAllowed);
},
restart: function(){
startFrame.classList.add("active");
reset.allCards(cards);
shuffleCards();
timer.counter("reset");
matchCount = 0;
totalMoves = 0;
movesAllowed = 0;
timeAllowed = 0;
time = 0;
}
}
var timer = {
counter: function(status){
var clock = document.querySelector(".timer");
var incrementTime = setInterval(function(){
time++;
var minutes = Math.floor(time / 60);
var seconds = Math.floor(time % 60);
if(seconds < 10){
clock.innerText = minutes + ":0" + seconds;
} else {
clock.innerText = minutes + ":" + seconds;
}
}, 1000);
var stopTime = function(){
clearInterval(incrementTime);
}
if(status === "start"){
alert("counting");
}
if(status === "reset"){;
alert("reset");
stopTime();
}
}
}
Two issues:
The variable that holds the interval, incrementTime, is local to the counter function. Once the counter function ends, incrementTime gets garbage collected, because no reference to the interval remains anymore. You need the interval variable to be persistent instead.
You're setting a new interval every time counter is called. You should probably only set an interval when status is start, otherwise the old interval will continue running and won't be stoppable (reassigning the interval a setInterval is assigned to doesn't clear the interval):
let interval; // <---- Persistent
var timer = {
counter: function(status){
var clock = document.querySelector(".timer");
if (status === 'start') {
interval = setInterval(() => { // <---- Assign to persistent variable
time++;
var minutes = Math.floor(time / 60);
var seconds = Math.floor(time % 60);
if(seconds < 10){
clock.innerText = minutes + ":0" + seconds;
} else {
clock.innerText = minutes + ":" + seconds;
}
}, 1000);
alert("counting");
} else if(status === "reset"){
var stopTime = function(){
clearInterval(interval); // <---- Clear persistent variable
}
alert("reset");
stopTime();
}
}
}
(It would also be a bit more elegant for the stopTime and interval functions to be persistent, rather than being re-created every time they're needed; eg, you might assign them to properties of timer)
The timer, start/pause button and reset button all work as expected.
The only bug it seems to have is, when I run the timer and reset it, it
won't start again. Only after I press the Start/Pause button 2 times it will run again.
Live demo: http://codepen.io/Michel85/full/pjjpYY/
Code:
var timerTime;
var time = 1500;
var currentTime;
var flag = 0;
var calculateTime
// Start your Timer
function startTimer(time) {
document.getElementById("btnUp").disabled = true;
document.getElementById("btnDwn").disabled = true;
timerTime = setInterval(function(){
showTimer();
return flag = 1;
}, 1000);
}
// Reset function
function resetTimer(){
clearInterval(timerTime);
document.getElementById('showTime').innerHTML=(calculateTime(1500));
document.getElementById("btnUp").disabled = false;
document.getElementById("btnDwn").disabled = false;
return time=1500;
}
// Pause function
function pauseTimer(){
clearInterval(timerTime);
currentTime = time;
document.getElementById('showTime').innerHTML=(calculateTime(time));
return flag = 0;
}
// Update field with timer information
function showTimer(){
document.getElementById("showTime").innerHTML=(calculateTime(time));
flag = 1;
if(time < 1){
resetTimer();
}
time--;
};
// Toggle function (Pause/Run)
function toggleTimmer(){
if(flag == 1){
pauseTimer();
} else {
startTimer();
}
}
/*
Round-time up or down
*/
// Set timer Up
function timeUp(){
time += 60;
document.getElementById("showTime").innerHTML=(calculateTime(time));
return time;
}
// Set timer Down
function timeDown(){
if(time > 60){
time-=60;
}
document.getElementById("showTime").innerHTML=(calculateTime(time));
return time;
}
/*
Break-time up down
*/
// Set timer Up
function breakUp(){
time += 60;
document.getElementById("showTime").innerHTML=(calculateTime(time));
return time;
}
// Set timer Down
function breakDown(){
if(time > 60){
time-=60;
}
document.getElementById("showTime").innerHTML=(calculateTime(time));
return time;
}
// Calculate the Days, Hours, Minutes, seconds and present them in a digital way.
function calculateTime(totalTime) {
// calculate days
var days = Math.floor(totalTime / 86400);
totalTime = totalTime % 86400
// calculate hours
var hours = Math.floor(totalTime / 3600);
totalTime = totalTime % 3600;
// calculate minutes
var minutes = Math.floor(totalTime / 60);
totalTime = totalTime % 60;
// calculate seconds
var seconds = Math.floor(totalTime);
function convertTime(t) {
return ( t < 10 ? "0" : "" ) + t;
}
// assign the variables
days = convertTime(days);
hours = convertTime(hours);
minutes = convertTime(minutes);
seconds = convertTime(seconds);
// Make sure the "00:" is present if empty.
if(days !== "00"){
var currentTimeString = days + ":" + hours + ":" + minutes + ":" + seconds;
return currentTimeString;
} else if (hours !== "00"){
var currentTimeString = hours + ":" + minutes + ":" + seconds;
return currentTimeString
} else if(minutes !== "0:00"){
var currentTimeString = minutes + ":" + seconds;
return currentTimeString
} else {
var currentTimeString = seconds;
return currentTimeString
}
}
Any help is welcome.
Thanks in advance.
Greets,
Michel
resetTimer needs to set flag to 0. If it leaves it set at 1, then toggleTimer will call pauseTimer rather than startTimer.
BTW, it's better style to use boolean values (true/false) for flags.
Just remove clearInterval(timerTime); in function resetTimer();
function resetTimer() {
//clearInterval(timerTime);
document.getElementById('showTime').innerHTML = (calculateTime(300));
document.getElementById("btnUp").disabled = false;
document.getElementById("btnDwn").disabled = false;
return time = 300;
}