SetInterval(), ClearInterval() timer questions for javascript - javascript

Hey guys so I'm trying to make an interval timer where the user inputs the number of rounds, length of working interval and length of resting interval. So if the user inputs 30 sec for work, 10 seconds for rest, and 10 rounds, the timer will display "WORK" for the title and run for 30 seconds,and then the title will change to "REST" and run for 10 more seconds (40 seconds total). Once 40 seconds is reached, the timer will go back to 0 and continue to do this for 9 more rounds (10 in total). I've never created a timer before so I am a little confused. I have gotten the timer to work, but I am having trouble changing the title and restarting the timer at each round. Below are copies of both my HTML and Javascript. any help is much appreciated!
Javascript:
var time = 0;
var running = 0;
var rounds = document.getElementById("numRounds").value;
var work = document.getElementById("numWork").value;
var rest = document.getElementyId("numRest").value;
function startPause()
{
if(document.getElementById("numRounds").value == "" | document.getElementById("numWork").value == "" |
document.getElementById("numRest").value == ""){
document.getElementById("error").innerHTML = "*All fields are required.";
}
else{
if(running == 0){
running = 1;
increment();
document.getElementById("startPause").innerHTML = "Pause";
}
else{
running = 0;
document.getElementById("startPause").innerHTML = "Resume";
}
}
}
function reset()
{
running = 0;
time = 0;
document.getElementById("startPause").innerHTML = "Start";
document.getElementById("output2").innerHTML = "00:00:00";
}
function work(){
time++;
var mins = Math.floor(time/10/60);
var secs = Math.floor(time/10 % 60);
var tenths = time % 10;
if(mins < 10){
mins = "0" + mins;
}
if(secs < 10){
secs = "0" + secs;
}
document.getElementById("output").innerHTML = mins + ":" + secs + ":" + tenths;
increment();
if(secs < work){
document.getElementById("work").innerHTML = "WORK";
}
var total = work + rest;
else if(secs >= work && secs< total){
document.getElementById("work") = "REST";
}
else{
clearInterval();
increment();
}
}
function increment()
{
if(running == 1){
for(var i=0;i<rounds; i++){
setTimeout(work(),100);
}
}
}
HTML:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE html
PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head>
<link href='http://fonts.googleapis.com/css?family=Nixie+One' rel='stylesheet' type='text/css'/>
<link rel="stylesheet" type="text/css" href="css/workitt.css"/>
<script type="text/javascript" src="js/stopwatch.js"></script>
<title>Workitt</title>
</head>
<body>
<div class="header" style="margin: 0 auto">
<h1><img src="images/workitt-header.jpg" alt="header" /></h1>
<ul id="navbar">
<li>Home</li>
<li> | </li>
<li>Custom Workout
<ul>
<li>Strength Workout</li>
<li>Cardio Workout</li>
<li>Stretching Workout</li>
<li>Swimming Workout</li>
<li>Office Workout</li>
</ul>
</li>
<li> | </li>
<li>Workout Library
<ul>
<li>Upper Body</li>
<li>Lower Body</li>
<li>Cardio</li>
<li>Core</li>
</ul>
</li>
<li> | </li>
<li>Fitness Accessories
<ul>
<li>Fitness Calculators</li>
<li>Fitness Timers</li>
<li>Fitness Journal</li>
<li><div class="clearfix"></div></li>
</ul>
</li>
</ul>
<p> </p>
</div>
<div> </div>
<div class="body" style="margin: 0 auto">
<div id="work">WORK</div>
<div id="output"><span class='left'> Round</span><span class='right'>Time </span><br/><span id="output2"> 0 00:00:00</span></div>
<p> </p>
<p> </p>
<p> </p>
<p> </p>
<div>
Number of Rounds: <input type="text" id="numRounds" name="Rounds" size="6"/>
Length of Work: <input type="text" id="numWork" name="Work" size="6"/> (seconds)
Length of Rest: <input type="text" id="numRest" name="Rest" size="6"/> (seconds)
</div>
<br/>
<div id="controls">
<button id="startPause" onclick="startPause()">Start</button>
<button onclick="reset()">Reset</button><br/><br/>
<span id="error"></span>
</div>
<br/>
</div>
<p> </p>
<p><br /><br /></p>
<hr style="width: 30%;margin-left: auto, margin-right: auto" />
<div style="text-align:center">Created By: Danielle Hafner<br/>
<script type="text/javascript">
<!--
document.write("Last Modified " + document.lastModified)
// -->
</script>
</div>
</body>
</html>

Let me answer your question with a simple example. So we want to make our timer a variable, that way we know what to clear when clearInterval is called. So for our timer we can do : myTimer = setInterval(...), then when we want to clear it we do: clearInterval(myTimer). So here is a small example, a basic counter that resets itself:
HTML:
<button id="play">Play</button>
<button id="stop">Stop</button>
<div id="counter">0</div>
JS:
var myTimer;
var count = 0;
document.getElementById("play").onclick = function()
{
myTimer = setInterval(counter, 1000);
document.getElementById("play").disabled = true;
}
document.getElementById("stop").onclick = function()
{
clearInterval(myTimer);
count = 0;
document.getElementById("play").disabled = false;
}
function counter()
{
count++;
document.getElementById("counter").innerHTML = count;
}
Fiddle here: http://jsfiddle.net/AniHouse/aCfEL/

Chew on this: http://jsfiddle.net/4cmEB/5/ :-)
Change rounds, states and lengths as you suit. I've added another state between rounds called wait, you can remove it, but remenber to remove also the corresponding time from lengths.

Related

Why does dynamically creating list items not work for the 10th item?

I am dynamically creating tabs as items of a list. For that I am using an input field called 'amount'. But I noticed some unwanted behavior for the 10th item. When using the arrow keys to increase or decrease the value of 'amount' the 10th item gets skipped and only gets created when I increase the value to 11, which creates both the 10th and 11th value at the same time. Every other value seems to work fine. Even inputting the number 10 and pressing enter works as intended, which is why I am even more confused.
This is my code:
const tabs = document.getElementById("tabs");
const amount = document.getElementById("amount");
var prevAmount = 0;
amount.addEventListener("change", function () {
if (amount.value < 1) {
amount.value = 1;
}
if (amount.value > prevAmount) {
while (tabs.children.length < amount.value) {
var newTab = document.createElement("li");
newTab.textContent = tabs.children.length + 1;
newTab.setAttribute("class", "tab");
tabs.appendChild(newTab);
}
} else {
while (tabs.children.length > amount.value) {
tabs.removeChild(tabs.lastChild);
}
}
prevAmount = amount.value;
});
amount.dispatchEvent(new Event("change"));
<!DOCTYPE html>
<html lang="en">
<body>
<div id="main-container">
<div id="amount-and-tabs-container">
<div class="container" id="amount-container">
<label id="amount-label" for="amount">Amount:</label>
<input type="number" id="amount" value="1" min="1">
</div>
<div class="container" id="tabs-container">
<ul class="tabs" id="tabs"></ul>
</div>
</div>
</div>
<!--<script src="form.js" defer></script>-->
<script src="tabs.js"></script>
</body>
</html>

Hide button until button is clicked

I want to hide the id="Watch" button.
until the class="button1" button is clicked
The countdown ends
Then the id="Watch" button appears.
function DelayRedirect() {
var seconds = 10;
var dvCountDown = document.getElementById("dvCountDown");
var lblCount = document.getElementById("lblCount");
dvCountDown.style.display = "block";
lblCount.innerHTML = seconds;
setInterval(function () {
seconds--;
lblCount.innerHTML = seconds;
if (seconds == 0) {
dvCountDown.style.display = "none";
window.location = "#Watch";
}
}, 1000);
}
<button class="button1" onclick="DelayRedirect()">continue</button>
<div id="dvCountDown" style = "display:none">
You will be redirected after <span id = "lblCount"></span> seconds.
</div>
<br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br>
<button id="Watch"><a class="button2" href="https://www.youtube.com/" target="_blank">Watch</i></a></button>
just set opacity 0 on #Watch and when button1 is clicked set opacity = 1 on #Watch. After the countdown reset #Watch opacity to 0.
You can do this,
Adding display to none in HTML by default,
<button style="display : none" id="Watch"><a class="button2" href="https://www.youtube.com/" target="_blank">Watch</i></a></button>
After this grab the button and set display to block once you click the button.
let one = document.querySelector(".button1");
let second = document.querySelector("#Watch");
one.addEventListener("click" , DelayRedirect);
function DelayRedirect() {
second.style.display = "block";
var seconds = 10;
var dvCountDown = document.getElementById("dvCountDown");
var lblCount = document.getElementById("lblCount");
dvCountDown.style.display = "block";
lblCount.innerHTML = seconds;
setInterval(function () {
seconds--;
lblCount.innerHTML = seconds;
if (seconds === 0) {
dvCountDown.style.display = "none";
window.location = "#Watch";
}
}, 1000);
}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<meta http-equiv="X-UA-Compatible" content="ie=edge" />
<title>My Website</title>
<!-- <script src="./src/index.js" defer ></script> -->
</head>
<body>
<button class="button1" >continue</button>
<div id="dvCountDown" style = "display:none">
You will be redirected after <span id = "lblCount"></span> seconds.
</div>
<br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br>
<button style="display : none" id="Watch"><a class="button2" href="https://www.youtube.com/" target="_blank">Watch</i></a></button>
<script src="./src/index.js"></script>
<!-- added defer also -->
</body>
</html>
You need to give it display: none by default, and after ten seconds give it display: inline, also you should stop the interval as it will run forever.
function DelayRedirect() {
var seconds = 10;
var dvCountDown = document.getElementById("dvCountDown");
var lblCount = document.getElementById("lblCount");
dvCountDown.style.display = "block";
lblCount.innerHTML = seconds;
const timeout = setInterval(function () {
seconds--;
lblCount.innerHTML = seconds;
if (seconds == 0) {
dvCountDown.style.display = "none";
document.getElementById('Watch').style.display = 'inline';
window.location = "#Watch";
clearInterval(timeout)
}
}, 1000);
}
#Watch {
display: none;
}
<button class="button1" onclick="DelayRedirect()">continue</button>
<div id="dvCountDown" style = "display:none">
You will be redirected after <span id = "lblCount"></span> seconds.
</div>
<br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br>
<button id="Watch"><a class="button2" href="https://www.youtube.com/" target="_blank">Watch</i></a></button>
This can be solved by using the hidden attribute on the button
For The Html
<button class="button1">continue</button>
<div id="dvCountDown" style = "display:none">
You will be redirected after <span id = "lblCount"></span> seconds.
</div>
<br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br>
<!--I would recommend using CSS to position your elements instead of <br> tags-->
<button id="Watch" hidden><a class="button2" href="https://www.youtube.com/" target="_blank">Watch</i></a></button>
The Javascript Portion is
const watchButton = document.getElementById('Watch');
const button1 = document.getElementByClassName('button1');
watchButton.addEventListener('click', delayRedirect() {
watchButton.removeAttribute('hidden');
watchButton.setTimeout(() => {
watchButton.setAttribute('hidden', 'true');
}
,10000)
})

Multiply a variable and store that value/output to screen

I have tried a bunch of ways to get this to work. I'm not a coder, and I have a frankensteined abomination of a counter program I put together as a replacement for our expensive counters that kept breaking on us (basically you input a value at the start of the day, and based on that value a calculation is done for the GOAL for the day).
I now want to add a GOAL BY LUNCH field/display that - however simply doing something like
var lunchgoal = goal * 0.69;
And then putting it on the page like I have with the goal field, does not seem to work.
I can either get it to display 0 - which seems like its displaying just the basic 0 value of goal before it is being incremented, or NaN - not a number.
So I thought I need to convert it to a number before multiplying it, but I nothing has worked for me for that. Right now I'm guessing it may be a matter of where they are contained on the page? I find that part of this confusing honestly. Any help is much appreciated, I would have thought this would be fairly simple!
Thank you!
HTML
<html>
<style>
body {background-color: Black;}
p {color: white;}
</style>
<div class="container">
<p> SAMS VALUE: <span id="output"> </span>
</p>
<p style="font-size:110px"> GOAL: <span id="output2"> </span>
</p>
<button style="background-color:white;width:20%;height:15%;font-size: 60px" type="button" onClick="onClick()">ACTUAL</button>
<p style="font-size:110px">Actual Count: <span id="clicks">0</span>
</p>
<div class="row">
<div class="col-sm-4"/>
<div class="col-sm-4">
<div id="timeContainer" class="well well-sm">
<time id="timerValue"/>
</div>
<div id="timerButtons">
<button id="start" class="btn btn-success" disabled="disabled">START</button>
<button id="stop" class="btn btn-danger">STOP</button>
<button id="reset" class="btn btn-default">RESET</button>
</div>
<div class="col-sm-4 col-sm-4 col-md-4"/>
</div>
</div>
</div>
</html>
Script
<script type="text/javascript">
document.addEventListener("keyup", function(event) {
if (event.keyCode === 109) {
event.preventDefault();
clicks += 1;
document.getElementById("clicks").innerHTML = clicks;
}
});
document.addEventListener("keyup", function(event) {
if (event.keyCode === 107) {
event.preventDefault();
document.getElementById("stop").click();
}
});
var clicks = 0;
function onClick() {
clicks += 1;
document.getElementById("clicks").innerHTML = clicks;
};
const input = parseInt(prompt("Enter a SAMS number: "));
var SAMSINPUT = input;
console.log(SAMSINPUT);
document.getElementById('output').innerHTML = SAMSINPUT;
var goal = 0;
var output2 = document.getElementById('output2');
//set interval for GOAL calculation
var samsInterval = setInterval(function doIncrement() {
if (clear == false) {
goal += 1;
output2.innerHTML = goal.toString();
}
}, SAMSINPUT * 1000);
var timerDiv = document.getElementById('timerValue'),
start = document.getElementById('start'),
stop = document.getElementById('stop'),
reset = document.getElementById('reset'),
clear = false,
t;
</script>
You have to do it in loop where goal is changing & you want this to change as well.otherwise it just stays on 0. i shortened the timer for demo purpose
document.addEventListener("keyup", function(event) {
if (event.keyCode === 109) {
event.preventDefault();
clicks += 1;
document.getElementById("clicks").innerHTML = clicks;
}
});
document.addEventListener("keyup", function(event) {
if (event.keyCode === 107) {
event.preventDefault();
document.getElementById("stop").click();
}
});
var clicks = 0;
function onClick() {
clicks += 1;
document.getElementById("clicks").innerHTML = clicks;
};
const input = parseInt(prompt("Enter a SAMS number: "));
var SAMSINPUT = input;
// console.log(SAMSINPUT);
document.getElementById('output').innerHTML = SAMSINPUT;
var goal = 0;
var output2 = document.getElementById('output2');
//set interval for GOAL calculation
var samsInterval = setInterval(function doIncrement() {
if (clear == false) {
goal += 1;
output2.innerHTML = goal.toString();
var lunchGoalNumber = goal * 0.69;
var output3 = document.getElementById("output3")
output3.innerHTML = lunchGoalNumber;
}
}, SAMSINPUT * 25);
var timerDiv = document.getElementById('timerValue'),
start = document.getElementById('start'),
stop = document.getElementById('stop'),
reset = document.getElementById('reset'),
clear = false;
<div class="container">
<p> SAMS VALUE: <span id="output"> </span></p>
<p style="font-size:50px"> GOAL: <span id="output2"> </span></p>
<p style="font-size:50px"> Lunch/GOAL: <span id="output3"> </span></p>
<button style="background-color:white;width:35%;height:15%;font-size: 60px" type="button" onClick="onClick()">ACTUAL</button>
<p style="font-size:50px">Actual Count: <span id="clicks">0</span></p>
<div class="row">
<div class="col-sm-4"></div>
<div class="col-sm-4">
<div id="timeContainer" class="well well-sm">
<time id="timerValue"></time>
</div>
<div id="timerButtons">
<button id="start" class="btn btn-success" disabled="disabled">START</button>
<button id="stop" class="btn btn-danger">STOP</button>
<button id="reset" class="btn btn-default">RESET</button>
</div>
<div class="col-sm-4 col-sm-4 col-md-4"></div>
</div>
</div>
</div>
</body>

Need to find out how to make a button go out

currently, I have a countdown script that counts down to 15.
<div id="skip" style="margin-top: 4px;">
<p> Please wait for <span id="timer" style="font-weight:bold;">15</span> seconds</p>
</div>
<div id="button">
<form action="http://website.com">
<input type="submit" style="display: none;" value="Go to website"/>
<script>
var count = 15;
function countDown(){
var timer = document.getElementById("timer");
if(count > 0){
count--;
timer.innerHTML = count;
setTimeout("countDown()", 1000);
}else{
document.getElementById("button");
}
}
countDown();
</script>
It does it's job and counts down to fifteen. What I actually want to happen is that when the 15 seconds is up, it will instead show a button that says "Go to website".
Basically it's like other shortener but it's not.
I don't think document.getElementByID doesnt work. I've been looking for a way to make the button appear but it's not working.
Start with the button hidden, and remove that condition when the timer expires. A common way to do that is to use a "hidden" utility class, as shown below.
Note: Count in this snippet is 3, because I get bored waiting for 15 seconds each iteration. :)
var count = 3;
function countDown(){
var timer = document.getElementById("timer");
var button;
var skipContainer;
if(count > 0){
count--;
timer.innerHTML = count;
setTimeout("countDown()", 1000);
}else{
skipContainer = document.getElementById("skip");
button = document.getElementById("button");
skipContainer.classList.add("hidden");
button.classList.remove("hidden");
}
}
countDown();
.hidden {
display: none;
}
<div id="skip" style="margin-top: 4px;">
<p> Please wait for <span id="timer" style="font-weight:bold;">15</span> seconds</p>
</div>
<div id="button" class="hidden">
<form action="http://website.com">
<input type="submit" value="Go to website"/>
</form>
</div>
You could use setInterval() function that I think is more natural for the count down process. I reuse most code from #Palpatim answer.
var count = 3;
var myVar = setInterval(function(){ countDown() }, 1000);
function countDown() {
var timer = document.getElementById("timer");
var button;
var skipContainer;
if(count > 0){
count--;
timer.innerHTML = count;
}else{
myStopFunction();
skipContainer = document.getElementById("skip");
button = document.getElementById("button");
skipContainer.classList.add("hidden");
button.classList.remove("hidden");
}
}
function myStopFunction() {
clearInterval(myVar);
}
.hidden {
display: none;
}
<div id="skip" style="margin-top: 4px;">
<p> Please wait for <span id="timer" style="font-weight:bold;">15</span> seconds</p>
</div>
<div id="button" class="hidden">
<form action="http://website.com">
<input type="submit" value="Go to website"/>
</form>
</div>

Copying the UI-Bootstrap code does not work? How do I use UI-Bootstrap?

I am trying to use components from the http://angular-ui.github.io/bootstrap/ page and am basically copying the code exacctly just to get the framework.
But it does not work seem to work, am I missing something general?
It is the exact same code and I have added the dependencies as far as I understand, which was the error in the other similar post.
For example with the carousel (ui.bootstrap.carousel), I copied the available html code into an html file index.html:
<!doctype html>
<html ng-app="ui.bootstrap.demo">
<head>
<script src="//ajax.googleapis.com/ajax/libs/angularjs/1.5.8/angular.js"></script>
<script src="//ajax.googleapis.com/ajax/libs/angularjs/1.5.8/angular-animate.js"></script>
<script src="//ajax.googleapis.com/ajax/libs/angularjs/1.5.8/angular-sanitize.js"></script>
<script src="//angular-ui.github.io/bootstrap/ui-bootstrap-tpls-2.3.0.js"></script>
<script src="example.js"></script>
<link href="//netdna.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet">
</head>
<body>
<div ng-controller="CarouselDemoCtrl">
<div style="height: 305px">
<div uib-carousel active="active" interval="myInterval" no-wrap="noWrapSlides">
<div uib-slide ng-repeat="slide in slides track by slide.id" index="slide.id">
<img ng-src="{{slide.image}}" style="margin:auto;">
<div class="carousel-caption">
<h4>Slide {{slide.id}}</h4>
<p>{{slide.text}}</p>
</div>
</div>
</div>
</div>
<div class="row">
<div class="col-md-6">
<button type="button" class="btn btn-info" ng-click="addSlide()">Add Slide</button>
<button type="button" class="btn btn-info" ng-click="randomize()">Randomize slides</button>
<div class="checkbox">
<label>
<input type="checkbox" ng-model="noWrapSlides">
Disable Slide Looping
</label>
</div>
</div>
<div class="col-md-6">
Interval, in milliseconds: <input type="number" class="form-control" ng-model="myInterval">
<br />Enter a negative number or 0 to stop the interval.
</div>
</div>
</div>
</body>
</html>
The js code I have copied into a js file called example.js:
angular.module('ui.bootstrap.demo', ['ngAnimate', 'ngSanitize', 'ui.bootstrap']);
angular.module('ui.bootstrap.demo').controller('CarouselDemoCtrl', function ($scope) {
$scope.myInterval = 5000;
$scope.noWrapSlides = false;
$scope.active = 0;
var slides = $scope.slides = [];
var currIndex = 0;
$scope.addSlide = function() {
var newWidth = 600 + slides.length + 1;
slides.push({
image: '//unsplash.it/' + newWidth + '/300',
text: ['Nice image','Awesome photograph','That is so cool','I love that'][slides.length % 4],
id: currIndex++
});
};
$scope.randomize = function() {
var indexes = generateIndexesArray();
assignNewIndexesToSlides(indexes);
};
for (var i = 0; i < 4; i++) {
$scope.addSlide();
}
// Randomize logic below
function assignNewIndexesToSlides(indexes) {
for (var i = 0, l = slides.length; i < l; i++) {
slides[i].id = indexes.pop();
}
}
function generateIndexesArray() {
var indexes = [];
for (var i = 0; i < currIndex; ++i) {
indexes[i] = i;
}
return shuffle(indexes);
}
// http://stackoverflow.com/questions/962802#962890
function shuffle(array) {
var tmp, current, top = array.length;
if (top) {
while (--top) {
current = Math.floor(Math.random() * (top + 1));
tmp = array[current];
array[current] = array[top];
array[top] = tmp;
}
}
return array;
}
});
For better readability you can also find the code here: https://plnkr.co/edit/YZULMBb0br4IuhV4dUug?p=preview
When I run it, it just shows this on the page:
Slide {{slide.id}}
{{slide.text}}
Why?
Try, adding http: before the links, plunker loads these references directly, but when you load the urls directly in browser it wont work.
Sometimes not necessarily because almost all browsers take that as the default protocol if the user does not specify it directly
You need to add http:
<script src="http://ajax.googleapis.com/ajax/libs/angularjs/1.5.8/angular.js"></script>
<script src="http://ajax.googleapis.com/ajax/libs/angularjs/1.5.8/angular-animate.js"></script>
<script src="http://ajax.googleapis.com/ajax/libs/angularjs/1.5.8/angular-sanitize.js"></script>
<script src="http://angular-ui.github.io/bootstrap/ui-bootstrap-tpls-2.3.0.js"></script>
<script src="example.js"></script>
<link href="http://netdna.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet">

Categories

Resources