Why is Javascript clearInterval not working on button click? - javascript

I have a timer program that counts down from 25:00 on "start" button click and is supposed to reset and clearInterval() on "reset" button click. When the timer reaches 0:00 the if statements all pass and resetTimer() is called which executes the clearInterval() which works in this instance. So in short: clearInterval() works when the if statements pass but not when I click the "reset" button. Can someone please explain to me why this is happening and offer a solution? Thank you!
//My Programs Code:
//Timer Widget
function timerStartReset(event) {
var minutes;
var seconds;
//decrease minutes html every minute
const minutesInterval = setInterval(() => {
minutes -= 1;
timerMinute.innerHTML = minutes;
}, 60000);
//decrease seconds html every second
const secondsInterval = setInterval(() => {
seconds -= 1;
timerSeconds.innerHTML = seconds < 10 ? `0${seconds}` : seconds;
//check if timer reaches 00:00
if (seconds <= 0) {
if (minutes <= 0) {
//stop and reset timer
//**HERE resetTimer() is called and clearInterval works**
resetTimer();
//return start button functionality
timerStartBtn.disabled = false;
//add a star
const addStar = `<i class="fas fa-star h2 mx-2"></i>`;
timerStarContainer.insertAdjacentHTML("beforeend", addStar);
localStorage.setItem("timer stars", timerStarContainer.innerHTML);
setTimeout(breakAlert, 1000);
}
seconds = 60;
}
}, 1000);
//start button function
if (event.target.id === "timer-start") {
startTimer();
event.target.disabled = true;
}
//reset button function
else {
//**HERE resetTimer() is called but clearInterval doesn't work**
resetTimer();
timerStartBtn.disabled = false;
}
//Reset timer
function resetTimer() {
//Reset to starting template
timerMinute.innerHTML = 25;
timerSeconds.innerHTML = "00";
//Clear minute/second timeout function
clearInterval(minutesInterval);
clearInterval(secondsInterval);
}
//start timer
function startTimer() {
//Change starting time and add them to page
minutes = 0;
seconds = 1;
timerMinute.innerHTML = minutes;
timerSeconds.innerHTML = seconds;
//start countdown
minutesInterval;
secondsInterval;
}
//Alert for breaks
function breakAlert() {
//If 4 star divs are added dynamically
if (timerStarContainer.childElementCount >= 4) {
swal(
"Great Job! You Did It!",
"Go ahead and take a 15-30 minute break!",
"success"
);
//remove all stars from DOM
timerStarContainer.innerHTML = "";
} else {
swal("Awesome!", "Please take a 5 minute break!", "success");
}
}
}
//End Timer Widget
const timerMinute = document.querySelector("#minute");
const timerSeconds = document.querySelector("#seconds");
const timerStartBtn = document.querySelector("#timer-start");
document.querySelector("#timer-btns").addEventListener("click", timerStartReset);
//Timer Widget
function timerStartReset(event) {
var minutes;
var seconds;
//decrease minutes html every minute
const minutesInterval = setInterval(() => {
minutes -= 1;
timerMinute.innerHTML = minutes;
}, 60000);
//decrease seconds html every second
const secondsInterval = setInterval(() => {
seconds -= 1;
timerSeconds.innerHTML = seconds < 10 ? `0${seconds}` : seconds;
//check if timer reaches 00:00
if (seconds <= 0) {
if (minutes <= 0) {
//stop and reset timer
resetTimer();
//return start button functionality
timerStartBtn.disabled = false;
}
seconds = 60;
}
}, 1000);
//start button function
if (event.target.id === "timer-start") {
startTimer();
event.target.disabled = true;
}
//reset button function
else {
resetTimer();
timerStartBtn.disabled = false;
}
//Reset timer
function resetTimer() {
//Reset to starting template
timerMinute.innerHTML = 0;
timerSeconds.innerHTML = 11;
//Clear minute/second timeout function
clearInterval(minutesInterval);
clearInterval(secondsInterval);
console.log("reset");
}
//start timer
function startTimer() {
//Change starting time and add them to page
minutes = 0;
seconds = 10;
timerMinute.innerHTML = minutes;
timerSeconds.innerHTML = seconds;
//start countdown
minutesInterval;
secondsInterval;
}
}
//End Timer Widget
<!-- Timer -->
<div>
<span id="minute">0</span>
<span>:</span>
<span id="seconds">11</span>
</div>
<div id="timer-btns">
<button id="timer-start">Start</button>
<button id="timer-reset">Reset</button>
</div>
<!-- End Timer -->

The variables minutesInterval and secondsInterval are local to this function. So every time you call the function, it starts new timers and creates new variables. When the code calls resetTimer(), it's only resetting the timer started by that invocation of timerStartReset, not the previous ones.
It works when the timer runs out, because the countdown code is in the same scope. But when you click the Reset button, that function is a new scope and can't access the variables from when the Start button was clicked.
The timer variables should be global variables that can be accessed from any invocation. And then there's no reason to use the same function for both buttons.
var minutesInterval;
var secondsInterval;
timerStartBtn.addEventListener('click', timerStart);
timerResetBtn.addEventListener('click', resetTimer);
function timerStart() {
resetTimer();
var minutes;
var seconds;
//decrease minutes html every minute
minutesInterval = setInterval(() => {
minutes -= 1;
timerMinute.innerHTML = minutes;
}, 60000);
//decrease seconds html every second
secondsInterval = setInterval(() => {
seconds -= 1;
timerSeconds.innerHTML = seconds < 10 ? `0${seconds}` : seconds;
//check if timer reaches 00:00
if (seconds <= 0) {
if (minutes <= 0) {
resetTimer();
//return start button functionality
timerStartBtn.disabled = false;
//add a star
const addStar = `<i class="fas fa-star h2 mx-2"></i>`;
timerStarContainer.insertAdjacentHTML("beforeend", addStar);
localStorage.setItem("timer stars", timerStarContainer.innerHTML);
setTimeout(breakAlert, 1000);
}
seconds = 60;
}
}, 1000);
startTimer();
//start timer
function startTimer() {
//Change starting time and add them to page
minutes = 0;
seconds = 1;
timerMinute.innerHTML = minutes;
timerSeconds.innerHTML = seconds;
//start countdown
minutesInterval;
secondsInterval;
}
//Alert for breaks
function breakAlert() {
//If 4 star divs are added dynamically
if (timerStarContainer.childElementCount >= 4) {
swal(
"Great Job! You Did It!",
"Go ahead and take a 15-30 minute break!",
"success"
);
//remove all stars from DOM
timerStarContainer.innerHTML = "";
} else {
swal("Awesome!", "Please take a 5 minute break!", "success");
}
}
}
//Reset timer
function resetTimer() {
//Reset to starting template
timerMinute.innerHTML = 25;
timerSeconds.innerHTML = "00";
//Clear minute/second timeout function
clearInterval(minutesInterval);
clearInterval(secondsInterval);
}
//End Timer Widget

Related

How to end my countdown timer when a button is clicked?

I'm trying to create a function that will end a countdown timer, or automatically make the minutes and seconds part of the countdown timer === 0; however, it seems that using clearInterval(time) doesn't seem to work! Could anyone point out how I might be able to achieve what I'm trying to do!
Note that I've made startingMinutes = 1 just for my ease.
Below is the countdown function and HTML:
// FUNCTION - countDown function that counts down from 8 minutes
const startingMinutes = 1;
let time = startingMinutes * 60;
function updateCountDown() {
const minutes = Math.floor(time / 60);
let seconds = time % 60;
seconds = seconds < 1 ? '0' + seconds : seconds;
document.getElementById("countdown").innerHTML = `${minutes}:${seconds}`;
time--;
time = time < 0 ? 0 : time;
if (minutes == 0 && seconds == 0) {
document.getElementById('tableStyle').style.display = "block";
document.getElementById('wordsIncluded').style.display = "block";
document.getElementById('show_header_one').style.display = "block";
recognition.abort(); //speech recognition stops when countdown timer ends
isListening = false;
}
//my attempt at clearing the countdowntimer!
window.addEventListener('DOMContentLoaded', function() {
document.getElementById("submit_button").addEventListener("click", function() {
clearInterval(time);
})});
HTML:
//where the countdown timer is displayed
<div id="circle"><p id="countdown">8:00</p></div>
//Click the below button and the countdown timer will end (minutes === 0 and seconds === 0)
<button id="submit_button" type="submit">Click to Submit</button>
To use clearInterval you need to pass it the value returned by setInterval
I have an example below using your code, where I pass the value from "setInterval" which I call "interval" to a function "stop" which calls "clearInterval" to stop the timer, and runs the code you were running.
let isListening = true;
const recognition = { abort: () => console.log('aborted') };
function updateCountDown(time) {
const minutes = Math.floor(time / 60);
const seconds = time % 60;
const timer = document.getElementById("countdown");
timer.textContent = `${minutes}:${seconds.toString().padStart(2, '0')}`;
}
function start(time) {
const interval = setInterval(() => {
if (--time) updateCountDown(time);
else stop(interval);
}, 1000);
document.getElementById("submit_button")
.addEventListener("click", () => stop(interval))
}
function stop(interval) {
updateCountDown(0); // This line sets time to 0
clearInterval(interval);
foo()
}
// I assume you want this to happen when the timer runs down or the button is clicked
function foo() {
document.getElementById('tableStyle').style.display = "block";
document.getElementById('wordsIncluded').style.display = "block";
document.getElementById('show_header_one').style.display = "block";
recognition.abort(); //speech recognition stops when countdown timer ends
isListening = false;
}
start(8*60)
#tableStyle, #wordsIncluded, #show_header_one { display: none; }
<p id="tableStyle">Table Style</p>
<p id="wordsIncluded">Words Included</p>
<p id="show_header_one">Show Header One</p>
<div id="circle">
<p id="countdown">8:00</p>
</div>
<button id="submit_button" type="submit">Click to Submit</button>
const startingMinutes = 1;
let time = startingMinutes * 60;
var abort_count_down = true;
function updateCountDown() {
if (abort_count_down) {
const minutes = Math.floor(time / 60);
let seconds = time % 60;
seconds = seconds < 1 ? '0' + seconds : seconds;
document.getElementById("countdown").innerHTML = `${minutes}:${seconds}`;
time--;
time = time < 0 ? 0 : time;
if (minutes == 0 && seconds == 0) {
document.getElementById('tableStyle').style.display = "block";
document.getElementById('wordsIncluded').style.display = "block";
document.getElementById('show_header_one').style.display = "block";
recognition.abort(); //speech recognition stops when countdown timer ends
isListening = false;
}
};
//my attempt at clearing the countdowntimer!
window.addEventListener('DOMContentLoaded', function() {
document.getElementById("submit_button").addEventListener("click", function() {
abort_count_down = false;
})});

How to make a pause/play button for timer on Javascript?

I am trying to make my pause and play button function on javascript, but I don't exactly know the logic behind all of it
I have tried putting the clearInterval() method in my pauseTimer function
var startButton = document.getElementById("start");
var startSound = document.getElementById("audio");
var timerSound = document.getElementById("timer");
var counter = document.getElementById("counter");
var middlebuttons = document.getElementsByClassName("middlebuttons");
var pauseButton = document.getElementById("pause");
var playButton = document.getElementById('play');
function pauseTimer(){
clearInterval();
alert("Pause button");
}
function playTimer(){
alert("Play button");
}
function countDown(minutes){
var seconds = 60;
var mins = minutes;
function tick(){
var current_minutes = mins - 1;
seconds --;
counter.innerHTML = current_minutes.toString() + ":" + (seconds < 10 ? "0" : "") + String(seconds);
if(seconds > 0){
setTimeout(tick, 10);
} else {
if(mins > 1){
countDown(mins - 1);
}
else if (mins && seconds === 0 ){
timerSound.play();
buttons();
}
}
}
tick();
}
pauseButton.addEventListener('click', pauseTimer, playAudio );
playButton.addEventListener('click', playTimer, playAudio );
Here's a thoroughly commented suggested solution. It uses a totalSeconds variable as the counter's source of truth.
The reason the timer variable is needed is because clearInterval wants to be told which interval to clear.
There's no "stop" button in this demo. If you want to reset the timer while it's running, just refresh the page.
(And it doesn't include any functions to play sounds, but you could add those at the appropriate points in the code.)
// Defines identifiers for accessing HTML elements
const minutesInput = document.getElementById("minutesInput"),
startButton = document.getElementById("startButton"),
pauseButton = document.getElementById("pauseButton"),
unpauseButton = document.getElementById("unpauseButton"),
counterDiv = document.getElementById("counterDisplay");
// Adds listeners and declares global variables
startButton.addEventListener('click', start);
pauseButton.addEventListener('click', pauseTimer);
unpauseButton.addEventListener('click', runTimer);
let totalSeconds; // global variable to count down total seconds
let timer; // global variable for setInterval and clearInterval
//Disables buttons that are not needed yet
disable(pauseButton);
disable(unpauseButton);
// Defines functions that get the minutes and seconds for display
function getMinutes(totalSeconds){
return Math.floor(totalSeconds / 60); // Gets quotient rounded down
}
function getSeconds(totalSeconds){
let seconds = totalSeconds % 60; // Gets remainder after division
return (seconds < 10 ? "0" + seconds : seconds) // Inserts "0" if needed
}
// Defines functions that manipulate the countdown
function start(){
totalSeconds = minutesInput.value * 60; // Sets initial value of totalSeconds based on user input
counterDiv.innerHTML = getMinutes(totalSeconds) + ":" + getSeconds(totalSeconds); // Initializes display
disable(minutesInput); disable(startButton); // Toggles buttons
runTimer();
}
function runTimer(){
// Is the main timer function, calls `tick` every 1000 milliseconds
timer = setInterval(tick, 1000);
disable(unpauseButton); enable(pauseButton); // Toggles buttons
}
function tick(){
if(totalSeconds > 0){
totalSeconds--; // Decreases total seconds by one
counterDiv.innerHTML = getMinutes(totalSeconds) + ":" + getSeconds(totalSeconds); // Updates display
}
else{
// The timer has reached zero. Let the user start again.
enable(minutesInput); enable(startButton);
disable(pauseButton); disable(unpauseButton);
}
}
function pauseTimer(){
// Stops calling `tick` and toggles buttons
clearInterval(timer);
disable(pauseButton); enable(unpauseButton);
}
// Defines functions to disable and re-enable HTML elements
function disable(element){ element.setAttribute("disabled",""); }
function enable(element){ element.removeAttribute("disabled"); }
counter{ height: 1em; width: 2em; margin: 0.4em; border: 1px solid grey }
<label>
How many minutes?:
<input type="number" id="minutesInput" value="1" />
</label>
<br />
<button id="startButton">Start</button>
<button id="pauseButton">Pause</button>
<button id="unpauseButton">Continue</button>
<div id="counterDisplay"></div>

Start timer every 1 minute Jquery

Trying to start my timer if the app is in idle start for 1 minute.
My timer is starting initially, how do I check whether my app is idle or not.
And also if the timer starts and interrupts in between then the timer should disappear and stay on the same page.
else redirect to home page.
JS:
var interval = setInterval(function() {
var timer = $('span').html();
var seconds = parseInt(timer,10);
seconds -= 1;
if (seconds < 0 ) {
seconds = 59;
}
else if (seconds < 10 && length.seconds != 2) seconds = '0' + seconds;
$('span').html(seconds);
if (seconds == 0)
clearInterval(interval);
}, 1000);
This is what I have tried:
Demo
$(document).ready(function(){
var idleInterval = setInterval(timerIncrement, 60000); // 1 minute
idleTime = 0;
//Zero the idle timer on mouse movement.
$(this).mousemove(function (e) {
idleTime = 0;
});
$(this).keypress(function (e) {
idleTime = 0;
});
});
//after every one minute this function will call and it check idleTime is
//increment if it is one then reload the page
function timerIncrement() {
idleTime = idleTime + 1;
if (idleTime > 1) { // 1 minutes
//alert();
window.location.reload();
}
}

How to restart javascript function using jquery issue

Hello I have a timer that executes via php/html like this
// timer
print "<script>countdown();</script>";
However I have a jquery warning dialog that looks like this, I would like for the javascript function to restart after they click the close button
// Create timeout warning dialog
$('body').append('<div title="Timeout"</div>');
$('#sessionTimeout-dialog').dialog({
autoOpen: false,
width: 600,
modal: true,
closeOnEscape: false,
open: function(event, ui) { $(".dialog").hide(); },
buttons: {
// Button two - closes dialog and makes call to keep-alive URL
"Continue Session": function() {
$(this).dialog('close');
clearTime();
$.ajax({
type: 'POST',
url: o.keepAliveUrl
});
countdown(); //I call the javascript function in hopes of making it go again
}
}
});
However I cant seem to make the timer actually restart once the button is click to continue. here is my timer code, what I'am I doing wrong? I call the javascript function after the button is closed but nothing happens it just goes to a negative number
// set minutes
var mins = 2;
// calculate the seconds (don't change this! unless time progresses at a different speed for you...)
var secs = mins * 60;
function countdown() {
setTimeout('Decrement()',1000);
}
function Decrement() {
if (document.getElementById) {
minutes = document.getElementById("minutes");
seconds = document.getElementById("seconds");
// if less than a minute remaining
if (seconds < 59) {
seconds.value = secs;
} else {
minutes.value = getminutes();
seconds.value = getseconds();
}
secs--;
setTimeout('Decrement()',1000);
}
}
function getminutes() {
// minutes is seconds divided by 60, rounded down
mins = Math.floor(secs / 60);
return mins;
}
function getseconds() {
// take mins remaining (as seconds) away from total seconds remaining
return secs-Math.round(mins *60);
}
It looks like your countdown function doesn't reset the timer, but only starts the decrement loop.
Add something like
function resetCountdown()
{
secs = mins * 2;
}
and call this function when the dialog is closed to reset the countdown. Do NOT call countdown() again as this will create another timer in addition to the already running one.
Also there is an error in your code:
if (seconds < 59) {
seconds.value = secs;
} else {
minutes.value = getminutes();
seconds.value = getseconds();
}
should be
if (secs < 59) {
minutes.value = 0;
seconds.value = secs;
} else {
minutes.value = getminutes();
seconds.value = getseconds();
}
I'm not completely sure this is what you want, but:
I like to restart certain timers when the window regains focus(from the dialog). Below is an example:
<html>
<head>
<script>
g = {};
g.timer = false;
g.count = false;
g.waittime = 3; //seconds for timer.
g.timeleft = (g.waittime * 100) - 10;
checktimer = function(){
if(g.timer === false){
g.timer = setTimeout(function(){
g.timer = false;
g.timeleft = g.waittime * 100;
alert("Hi!");
},g.waittime * 1000);
}
if(g.count === false){
g.count = setInterval(function(){
g.timeleft-=10;
document.getElementById("disp").innerText =(g.timeleft/100).toString().match(/^\d+(?:\.\d{0,2})?/);
},100);
}
}
window.onfocus = function() {
checktimer();
};
</script>
</head>
<body onload="checktimer();">
<div>Time Left: <span id="disp">0</span> Seconds.</div>
</body>
</html>

setInterval recount?

var sec = 10
var timer = setInterval(function() {
$('#timer span').text(sec--);
if (sec == -1) {
clearInterval(timer);
} }, 1000);
html
<div id="timer"><span>10</span> seconds</div>
Recount
What I want to do when I click recount is to recount back to 10 seconds the timer?
How can I possibly done it?
It is better to use setInterval() or setTimeout()?
Factor out your code into functions so you can call the same code on startup or when the link is clicked. You can see it working here: http://jsfiddle.net/jfriend00/x3S7j/. This even allows you to click the link during the countdown and it will start over.
$("#recount").click(function() {
initCounter(10);
});
var remainingTime;
var runningInterval = null;
function initCounter(duration) {
function stopCounter() {
if (runningInterval) {
clearInterval(runningInterval);
runningInterval = null;
}
}
stopCounter(); // stop previously running timer
remainingTime = duration; // init duration
$('#timer span').text(remainingTime); // set initial time remaining
runningInterval = setInterval(function() { // start new interval
$('#timer span').text(remainingTime--);
if (remainingTime < 0) {
stopCounter();
}
}, 1000);
}
initCounter(10);
You can just add a click handler and factor out your code in a separate method:
var sec = 10;
var timer;
function startCountdown() {
if (timer) clearInterval(timer);
sec = 10;
timer = setInterval(function() {
$('#timer span').text(sec--);
if (sec == -1) {
clearInterval(timer);
}
}, 1000);
}
$(function() {
startCountdown();
$("#recount").click(startCountdown);
});
Working JSFiddle
When you click recount, you should
sec = 10;
clearInterval(timer);
timer = setInterval(that_function, 1000);
Also, there's a difference between setInterval and setTimeout. setInterval schedules the function to be called every some milliseconds. setTimeout schedules the function to be called once, after some milliseconds.

Categories

Resources