Resetting setInterval timer for three different interval buttons - javascript

Problem: I have three buttons that set different timers. When I click the timer buttons after a first click, it doesn't reset the timer, but continues the timer where it left off.
Desired Result: When I click the timer buttons (Pomodoro, lng break, shrt break) I want the timer to reset. EG: Pomodoro is set for 24mins 60seconds. If I click the same Pomodoro button when the timer is say, 23 mins, I want it to reset to the original 24mins, 60 seconds.
Re-created the situation:
Here is my javascript, and html. I will also post a JSBin since I am still not sure how to do code snippets yet.
JavaScript:
// Problem: Pomodor timer does not have functionality
// Solution: Add functionality to the pomodor timer.
// IF a break timer is running WHILE another is clicked, stop running timer, start clicked timer.
// Reset current interval time on reset button.
// If break buttons are clicked more than once, reset the time.
window.onload = function() {
var pomodoro = document.querySelector('#set-time'),
longBreak = document.querySelector('#long-brk'),
shortBreak = document.querySelector('#short-brk'),
stopButton = document.querySelector('#stop'),
startButton = document.querySelector('#start'),
resetButton = document.querySelector('#reset'),
container = document.querySelector('#container'),
timer = document.querySelector('#timer'),
seconds = 60; //set seconds
// Click event for break timers.
container.addEventListener('click', function(e) {
// store event target
var el = e.target;
if (el === pomodoro) {
setPomodoro();
} else if (el === longBreak) {
setLongBreak();
} else if (el === shortBreak) {
setShortBreak();
}
e.stopPropagation();
}, false);
// 1.1a Create a timer that counts down from 25 minutes.
function setPomodoro() {
var pomodoroMins = 24;
var intervalID = setInterval(function() { //set unique interval ID for each SI func.
timer.innerHTML = pomodoroMins + ':' + seconds;
seconds--;
if (seconds === 0) {
pomodoroMins--;
seconds = 60;
}
}, 1000);
// 2.2 When stop button is clicked, timer stops
stopButton.addEventListener('click', function(){
clearInterval(intervalID);
}, false);
}
// 1.2a Create a timer that counts down from 10 minutes
function setLongBreak() {
var longBreakMins = 9;
var intervalID2 = setInterval(function() {
timer.innerHTML = longBreakMins + ':' + seconds;
seconds--;
if (seconds === 0) {
longBreakMins--;
seconds = 60;
}
}, 1000);
stopButton.addEventListener('click', function(){
clearInterval(intervalID2);
}, false);
}
// 1.3a Create a timer that counts down from 5 minutes.
function setShortBreak() {
var shortBreakMins = 4;
var intervalID3 = setInterval(function() {
timer.innerHTML = shortBreakMins + ':' + seconds;
seconds--;
if (seconds === 0) {
shortBreakMins--;
seconds = 60;
}
}, 1000);
stopButton.addEventListener('click', function() {
clearInterval(intervalID3);
}, false);
}
};
HTML:
<!DOCTYPE html>
<html>
<head>
<title>Pomodoro Timer</title>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="stylesheet" href="normalize.css">
<link rel="stylesheet" href="main.css">
</head>
<body>
<div id="container">
<header>
<div id="header"><h1>Pomodoro Timer</h1></div>
</header>
<div class="row">
<ul id="breaks">
<li><input type="submit" value="Pomodoro" id="set-time"></li>
<li><input type="submit" value="Long Break" id="long-brk"></li>
<li><input type="submit" value="Short Break" id="short-brk"></li>
</ul>
</div>
<h1 id=timer></h1>
<div class="row">
<ul id="buttons">
<li><input type="submit" value="Start" id="start"></li>
<li><input type="submit" value="Stop" id="stop"></li>
<li><input type="submit" value="Reset" id="reset"></li>
</ul>
</div>
<footer>
<p>© Laere 2016</p>
</footer>
</div>
<script src="script.js"></script>
</body>
</html>
JSBin: http://jsbin.com/fodagejohi/1/edit?html,js,output
Appreciate the guidance.

Related

How to execute onclick methood inside javascript code

I want execute onclick event after the 5 second timer gone and second button enabled.. Here is my code.
Download Video
Javascript code
<script>
var towait = 5;
var selector = "#downloadvideo";
function counter() {
if (towait == 0) {
$(selector).text("Start Download");
var srclink = '<?= $url;?>';
$(selector).attr('href', srclink).prop('href', srclink).prop('disabled', false);
return;
}
$(selector).text("Wait " + towait + " s").prop('disabled', true);
towait--;
setTimeout(counter, 1000);
}
$(selector).one('click', function(e) {
counter();
return false;
});
</script>
Try to add setInterval and clearInterval functions to your code. Below is a simple 10 seconds timer just to demonstrate. For full disclosure, not all of the code is my own some of it I've copied from this answer.
var timeleft = 10;
var b = document.querySelector('#btn');
b.addEventListener('click', () => {
var downloadTimer = setInterval(function(){
if(timeleft <= 0){
clearInterval(downloadTimer);
}
document.getElementById("progressBar").value = 10 - timeleft;
timeleft -= 1;
}, 1000);
});
input[type='number'] {
border: 0;
font-size: 15px;
}
input[type=number]::-webkit-inner-spin-button {
-webkit-appearance: none;
}
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width">
<title>JS Bin</title>
</head>
<body>
<div>
<button id='btn'>Click</button>
<input type='number' value="0" max="10" id="progressBar"></input>
</div>
</body>
</html>
You can do something like this. Just update the DownloadVideo function to what you need to happen when the 'Start Downloading' button is pressed.
EDIT:
Using an <a> tag with a href instead.
let waitTime = 5 // Time to wait in seconds before download is available
const selector = document.getElementById('downloadvideo')
selector.onclick = () => {
selector.textContent = 'Wait ' + waitTime + ' s'
selector.disabled = true
selector.onclick = () => {}
const inter = setInterval(() => {
waitTime--
if (waitTime == 0) {
clearInterval(inter)
selector.textContent = 'Start Downloading'
selector.href = 'https://www.google.com' // replace with the desired url
} else {
selector.textContent = 'Wait ' + waitTime + ' s'
}
}, 1000)
}
<button>
<a id="downloadvideo" class="btn btn-primary btn-lg"> Download Video </a>
</button>

Javascript Start/Stop button changes innerHTML and starts timer but doesn't fulfil any of the other part of function

I have a button which I am trying to use as a start and stop for an event which starts or stops a countdown timer. However it currently only starts and changes to the stop but will not change back to start or stop the timer from counting down.
Is there a better way of doing this? I've also included the reset button as I've tried to reset things when it it's pushed but it currently just changes back to the start, but the start won't fire again after I have done this.
((d) => {
let btn = d.getElementById("btn");
let reset = d.getElementById("reset");
let countdown = d.getElementById("countdown");
let counter;
let startTime = 1500;
let timerFormat = (s) => {
return (s - (s %= 60)) / 60 + (9 < s ? ":" : ":0") + s;
};
countdown.innerHTML = timerFormat(startTime);
let timer = () => {
startTime--;
countdown.innerHTML = timerFormat(startTime);
if (startTime === 0) clearInterval(counter);
};
btn.addEventListener("click", () => {
if (stop) {
start();
btn.innerHTML = "Stop";
} else {
stop();
btn.innerHTML = "Start";
}
});
let start = () => {
counter = counter || setInterval(timer, 1000);
};
let stop = () => {
clearInterval(counter);
counter = undefined;
};
reset.onclick = () => {
startTime = 1500;
countdown.innerHTML = timerFormat(startTime);
if (btn.innerHTML === "Stop") {
btn.innerHTML = "Start";
}
};
})(document);
<!DOCTYPE html>
<html lang="en">
<head>
<title>Document</title>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<link rel="stylesheet" href="../styles/styles.css" />
<script defer src="../JS/timer.js"></script>
</head>
<body>
<div id="countdown"></div>
<div class="btn__container">
<button class="btn" id="btn">Start</button>
<button class="btn" id="reset">Reset</button>
</div>
</body>
</html>
Your problem is in how you are determining whether to start or stop:
if (stop) {
stop is a function, so it has a "truthy" value and your if statement will always evaluate to true. Instead, check the existence of counter.
Other:
Don't use .innerHTML if you can help it and certainly not when the
string you are working with doesn't contain any HTML. .innerHTML
has security and performance implications. Instead, use
.textContent.
While a timer isn't going to be 100% accurate for timekeeping, you
can make the counter a little bit more accurate by having the
callback run just a little under every second. The reason being that
running every second means you run the risk of possibly skipping over
a second on the counter if the timer doesn't run exactly one second
later.
((d) => {
let btn = d.getElementById("btn");
let reset = d.getElementById("reset");
let countdown = d.getElementById("countdown");
let counter;
let startTime = 1500;
let timerFormat = (s) => {
return (s - (s %= 60)) / 60 + (9 < s ? ":" : ":0") + s;
};
countdown.textContent = timerFormat(startTime);
let timer = () => {
startTime--;
countdown.textContent = timerFormat(startTime);
if (startTime === 0) clearInterval(counter);
};
btn.addEventListener("click", () => {
if (counter) {
stop();
btn.textContent = "Start";
} else {
start();
btn.textContent = "Stop";
}
});
let start = () => {
counter = counter || setInterval(timer, 950);
};
let stop = () => {
clearInterval(counter);
counter = null;
};
reset.onclick = () => {
startTime = 1500;
countdown.textContent = timerFormat(startTime);
if (btn.textContent === "Stop") {
btn.textContent = "Start";
}
};
})(document);
<!DOCTYPE html>
<html lang="en">
<head>
<title>Document</title>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<link rel="stylesheet" href="../styles/styles.css" />
<script defer src="../JS/timer.js"></script>
</head>
<body>
<div id="countdown"></div>
<div class="btn__container">
<button class="btn" id="btn">Start</button>
<button class="btn" id="reset">Reset</button>
</div>
</body>
</html>

Pause and start JS countdown timer

I am trying to develop a centurion countdown timer for my website. It is a drinking game.
The way the timer works is: It is a 60 second countdown timer. Everytime the timer hits 0 it will +1 a shot counter and restart. It will do this 100 times.
The game is you must do 1 shot, every minute for 100 minutes. I am a beginner at JS and I am learning a lot, but I am seriously struggling to get this to work the way I want it to.
All I need is a "Start" Button, a "Pause" button and a "Reset" button but I can't seem to find a way to make these buttons work without messing the timer up.
Here is the HTML code:
<div class="inner">
<h1 class="heading alt">Centurions Timer</h1>
<p>1 Shot. Every Minute. 100 Minutes.</p>
<p>___________________________________</p>
<div id="timer">
<p id="seconds">60</p>
<p id="shots">0</p>
</div>
<input type="button" value="Start" onclick="timer()">
<input type="button" value="Pause" onclick="clearInterval(myTimer)">
</div>
and here is the JS code:
var seconds = 60;
var shots = 0;
var timer;
var c = 60;
function timer() {
timer = setInterval(myTimer, 1000)
}
function myTimer() {
document.getElementById("seconds").innerHTML = --c;
if (c == 0) {
shots = shots + 1;
c = 60;
}
document.getElementById("shots").innerHTML = shots;
}
If anyone could help me and show me what I am doing wrong and how I can make the code better, please do!
First, consider renaming either your method timer() or variable timer to disambiguate between the two.
Next, setInterval() returns an interval ID, which you store in timer.
clearInterval() takes the interval ID as the parameter, so try passing it the timer variable instead of myTimer (a function)
Little bit clean up needed. For clearInterval, u have to id of timer to clear
var seconds = 60;
var shots = 0;
var timer;
var c = 60;
function start() {
clearInterval(timer)
timer = setInterval(( ) =>{
updateUi()
}, 1000);
}
function pause() {
clearInterval(timer)
}
function updateUi() {
document.getElementById("seconds").innerHTML = --c;
if (c == 0) {
shots = shots + 1;
c = 60;
}
document.getElementById("shots").innerHTML = shots;
}
<div class="inner">
<h1 class="heading alt">Centurions Timer</h1>
<p>1 Shot. Every Minute. 100 Minutes.</p>
<p>___________________________________</p>
<div id="timer">
<p id="seconds">60</p>
<p id="shots">0</p>
</div>
<input type="button" value="Start" onclick="start()">
<input type="button" value="Pause" onclick="pause()">
</div>
You can also use Pub Sub model, to make code looks clean.
var seconds = 60;
var shots = 0;
var c = 60;
function Emitter() {
this.cb;
this.on = cb => {
this.cb = cb;
};
this.emit = () => {
this.cb && this.cb();
};
this.cancel = () => {
this.cb = null;
};
}
const emitter = new Emitter();
const tick = () => {
setInterval(() => {
emitter.emit();
}, 1000);
};
tick()
function start() {
emitter.on(updateUi);
}
function pause() {
emitter.cancel();
}
function updateUi() {
document.getElementById("seconds").innerHTML = --c;
if (c == 0) {
shots = shots + 1;
c = 60;
}
document.getElementById("shots").innerHTML = shots;
}
<div class="inner">
<h1 class="heading alt">Centurions Timer</h1>
<p>1 Shot. Every Minute. 100 Minutes.</p>
<p>___________________________________</p>
<div id="timer">
<p id="seconds">60</p>
<p id="shots">0</p>
</div>
<input type="button" value="Start" onclick="start()">
<input type="button" value="Pause" onclick="pause()">
</div>
<div class="inner">
<h1 class="heading alt">Centurions Timer</h1>
<p>1 Shot. Every Minute. 100 Minutes.</p>
<p>___________________________________</p>
<div id="timer">
<p id="minutes">100</p>
<p id="seconds">60</p>
<p id="shots">0</p>
</div>
<input type="button" value="START" onclick="start()">
<input type="button" value="PAUSE" onclick="pause()">
<input type="button" value="RESET" onclick="reset()">
</div>
Changed the onclick functions to something more meaningful. Added an extra button and some more logic to auto-stop when hitting the 100 minutes.
var seconds = 60,
minutes = 100,
shots = 0;
timer = "";
// this will just stop the timer, if you click start it will resume from where it left off
function pause() {
clearInterval(timer);
}
// resets seconds/minutes/shots, stops game
function reset() {
clearInterval(timer);
seconds = 60;
minutes = 100;
shots = 0;
timer = "";
document.getElementById("minutes").innerHTML = minutes;
document.getElementById("seconds").innerHTML = c;
document.getElementById("shots").innerHTML = shots;
}
// starts game from wherever it was left
function start() {
timer = setInterval(function() {
document.getElementById("seconds").innerHTML = c--;
if (c === 0) {
document.getElementById("minutes").innerHTML = --minutes;
// when 100 minutes are up, game will stop and reset
if (minutes === 0) {
reset();
}
shots++;
c = 60;
}
document.getElementById("shots").innerHTML = shots;
}, 1000)
}

JavaScript countdown timer not display button after reset

I am trying to create html5 app that have a timer. After time end in 10 second, it will display a button. Supposed to be, once user click on the button, a popup will displayed and it will count the button click in a variable and reset the timer. The process will loop again. The issue is, after user click on the button, and after the timer finished countdown for second time, the button is not displaying.
Here is the Js codes:
<!-- Timer countdown -->
<script type=text/javascript>
var clicks = 0;
function showTimer(selector, seconds)
{
var startTime = Date.now();
var interval;
function showRemaining()
{
var delta = Date.now() - startTime; // milliseconds
var deltaSeconds = delta / (1000);
if (deltaSeconds < seconds) {
// display minutes remaining
$(selector).text(Math.round(seconds - deltaSeconds));
} else {
$(selector).text(0);
clearInterval(interval);
}
}
interval = setInterval(showRemaining, 1000);
showRemaining();
}
$(document).ready(function()
{
showTimer("#countdown", 10);
});
setTimeout(function()
{
$("#proceed").show();
}, 10000);
//when click button
function onClick() {
clicks += 1;
document.getElementById("proceed").style.visibility="hidden";
alert("Getting the message");
document.getElementById("clicks").innerHTML = clicks;
showTimer("#countdown", 10);
};
</script>
This is the HTML:
<h1>Test</h1>
<br>
<p ><span id="countdown"></span><br>
Timer Here<br>
<button type="button" id="proceed" onclick="onClick()">Click</button><br>
<a id="clicks">0</a></p>
you forget to show your button again, the way you did it , it's going to hide. remove the setTimeout since you know the end of your timer and also can repeat it.
var clicks = 0;
var interval = -1;
function showTimer(selector, seconds)
{
var startTime = Date.now();
function showRemaining()
{
var delta = Date.now() - startTime; // milliseconds
var deltaSeconds = delta / (1000);
if (deltaSeconds < seconds) {
// display minutes remaining
$(selector).text(Math.round(seconds - deltaSeconds));
} else {
$(selector).text(0);
clearInterval(interval);
$("#proceed").show(); // Look at here
}
}
if( interval > -1 ) clearInterval(interval);
interval = setInterval(showRemaining, 1000);
showRemaining();
}
$(function() {
showTimer("#countdown", 10);
});
//when click button
function onClick() {
$("#proceed").hide();
alert("Getting the message");
$("#clicks").text(++clicks);
showTimer("#countdown", 10);
};
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<h1>Test</h1>
<br>
<p >
<span id="countdown"></span><br>
Timer Here<br>
<button type="button" id="proceed" onclick="onClick()">Click</button><br>
<a id="clicks">0</a>
</p>
include jquery file link,
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.0/jquery.min.js" type="text/javascript"></script>

Re-starting a timer after stopping it

Problem: When I click my start button after stopping my timer, I can't seem to get the timer to resume.
Desired result: For any given timer, when I click the start button, after clicking the stop button, I want the time to resume where it left off.
I figured that when clicking the start button, it would just call the setInterval function again after being cleared, however, I am having issues figuring that out.
I have the stop event in each function in the same scope as the intervalID var's, which hold the setInterval functions itself. Which is why the stop button works. Calling the timer functions(setPomodoro, setLongBreak, setShortBreak) resets their timer's to the original state. I can't seem to grasp how to resume from the timer's time when it's stopped.
JSBIN: http://jsbin.com/bucalequsi/edit?html,js,output
Re-creation:
// Problem: Pomodor timer does not have functionality
// Solution: Add functionality to the pomodor timer.
// IF a break timer is running WHILE another is clicked, stop running timer, start clicked timer.
// Reset current interval time on reset button.
// If break buttons are clicked more than once, reset the time.
window.onload = function() {
var pomodoro = document.querySelector('#set-time'),
longBreak = document.querySelector('#long-brk'),
shortBreak = document.querySelector('#short-brk'),
stopButton = document.querySelector('#stop'),
startButton = document.querySelector('#start'),
resetButton = document.querySelector('#reset'),
container = document.querySelector('#container'),
actionButtons = document.querySelector('#buttons'),
timer = document.querySelector('#timer');
// Click event for break timers.
container.addEventListener('click', function(e) {
// store event target
var el = e.target;
if (el === pomodoro) {
setPomodoro();
} else if (el === longBreak) {
setLongBreak();
} else if (el === shortBreak) {
setShortBreak();
}
e.stopPropagation();
}, false);
// 1.1a Create a timer that counts down from 25 minutes.
function setPomodoro() {
var mins = 24;
var secs = 60;
var intervalID = setInterval(function() { //set unique interval ID for each SI func.
timer.innerHTML = mins + ':' + secs;
secs--;
if (secs === 0) {
mins--;
secs = 60;
}
}, 1000);
// 2.2 When stop button is clicked, timer stops
stopButton.addEventListener('click', function() {
clearInterval(intervalID);
}, false);
}
// 1.2a Create a timer that counts down from 10 minutes
function setLongBreak() {
var mins2 = 9;
var secs2 = 60;
var intervalID2 = setInterval(function() {
timer.innerHTML = mins2 + ':' + secs2;
secs2--;
if (secs2 === 0) {
mins2--;
secs2 = 60;
}
}, 1000);
stopButton.addEventListener('click', function(){
clearInterval(intervalID2);
}, false);
}
// 1.3a Create a timer that counts down from 5 minutes.
function setShortBreak() {
var mins3 = 4;
var secs3 = 60;
var intervalID3 = setInterval(function() {
timer.innerHTML = mins3 + ':' + secs3;
secs3--;
if (secs3 === 0) {
mins3--;
secs3 = 60;
}
}, 1000);
stopButton.addEventListener('click', function() {
clearInterval(intervalID3);
}, false);
}
};
HTML:
<!DOCTYPE html>
<html>
<head>
<title>Pomodoro Timer</title>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="stylesheet" href="normalize.css">
<link rel="stylesheet" href="main.css">
</head>
<body>
<div id="container">
<header>
<div id="header"><h1>Pomodoro Timer</h1></div>
</header>
<div class="row">
<ul id="breaks">
<li><input type="submit" value="Pomodoro" id="set-time"></li>
<li><input type="submit" value="Long Break" id="long-brk"></li>
<li><input type="submit" value="Short Break" id="short-brk"></li>
</ul>
</div>
<h1 id=timer></h1>
<div class="row">
<ul id="buttons">
<li><input type="submit" value="Start" id="start"></li>
<li><input type="submit" value="Stop" id="stop"></li>
<li><input type="submit" value="Reset" id="reset"></li>
</ul>
</div>
<footer>
<p>© Laere 2016</p>
</footer>
</div>
<script src="script.js"></script>
</body>
</html>
When the set... functions are started with the buttons, you always initialise the times to starting values. Instead, if there is a timer already running you have to parse the paused time string into minutes and seconds and use those values to set your vars mins and secs.
Maybe something like this will work?
function setPomodoro() {
if(timer.innerHTML.length > 0){
var t = timer.innerHTML.split(':');
var mins = parseInt(t[0]);
var secs = parseInt(t[1]);
}
else{
var mins = 24;
var secs = 60;
}
var intervalID = setInterval(function() { //set unique interval ID for each SI func.
timer.innerHTML = mins + ':' + secs;
secs--;
if (secs === 0) {
mins--;
secs = 60;
}
}, 1000);
// 2.2 When stop button is clicked, timer stops
stopButton.addEventListener('click', function() {
clearInterval(intervalID);
}, false);
}

Categories