I'm building a Pomodoro Clock to improve my JavaScript, but I have a few issues. For starters, the increment/decrement buttons for the break do not update the time in the display. Secondly, the Session time doesn't restart after the first break period. Can anyone, please, advise me of where I went wrong?
The HTML:
<html>
<head>
<title>David Hall - Pomodoro Clock Zipline</title>
<link href="https://fonts.googleapis.com/css?family=Orbitron" rel="stylesheet" type="text/css" />
<link rel="stylesheet" href="http://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/css/bootstrap.min.css">
<link href="main.css" rel="stylesheet" type="text/css" />
</head>
<body>
<div class="container">
<h1 class="center">Pomodoro Clock</h1>
<div class="row">
<div class="center">
<div class="col-sm-6">Break Length</div>
<div class="col-sm-6">Work Length</div>
<div class="col-sm-6" id="center">
<div class="btn-group">
<button type="button" class="btn btn-success" id="decreaseBreak"><span class="glyphicon glyphicon-menu-left"></span>
<button type="button" class="btn btn-success"><span id="breakTime">5</span>
<button type="button" class="btn btn-success btn" id="increaseBreak"><span class="glyphicon glyphicon-menu-right"></span></div>
</div>
<div class="col-sm-6">
<div class="btn-group">
<button type="button" class="btn btn-success" id="decreaseWork"><span class="glyphicon glyphicon-menu-left"></span>
<button type="button" class="btn btn-success"><span id="workTime">25:00</span>
<button type="button" class="btn btn-success btn" id="increaseWork"> <span class="glyphicon glyphicon-menu-right"></span></div>
</div>
<br />
<br />
<br />
<br />
<div class="center">
<div class="boxed">
<br />
<span id="boxText">SESSION</span>
<br />
<br />
<br />
<span id="display"></span>
<br />
<span id="timerStatus"></span>
</div>
<br />
<button type="button" class="btn btn-success btn-sm" id="start">Start</button>
<button type="button" class="btn btn-success btn-sm" id="pause">Pause</button>
<button type="button" class="btn btn-success btn-sm" id="reset">Reset</button>
</div>
</div>
<script src='http://cdnjs.cloudflare.com/ajax/libs/jquery/2.1.3/jquery.min.js'> </script>
<script src='http://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/js/bootstrap.min.js'></script>
<script src="script.js"></script>
</body>
</html>
And the JavaScript:
var myInterval;
var workTime = document.getElementById("workTime").innerHTML = 25;
var breakTime = document.getElementById("breakTime").innerHTML = 5;
var remainSec = workTime * 60;
document.getElementById("display").innerHTML = workTime;
function startWork() {
document.getElementById("start").disabled = true;
timer(callback);
}
function pauseTime() {
clearInterval(myInterval);
document.getElementById("start").disabled = false;
}
function displayTime(remainingTime) {
if (remainingTime % 60 >= 10) {
document.getElementById('display').innerHTML = Math.floor(remainingTime / 60) + ':' + Math.floor(remainingTime % 60);
} else {
document.getElementById('display').innerHTML = Math.floor(remainingTime / 60) + ':' + "0" + Math.floor(remainingTime % 60);
}
}
function timer(pomodoro) {
var remainingTime = remainSec;
myInterval = setTimeout(function() {
displayTime(remainingTime);
if (remainingTime >= 0) {
remainSec--;
timer(pomodoro);
} else {
clearInterval();
pomodoro();
}
}, 1000);
}
var callback = function() {
console.log('callback');
document.getElementById('timerStatus').innerHTML = "Take a break!";
remainSec = breakTime * 60;
timer(callbackRest)
};
var callbackRest = function() {
clearInterval(myInterval);
console.log('callbackRest');
document.getElementById('timerStatus').innerHTML = "Begin";
remainSec = workTime * 60;
document.getElementById("start").disabled = false;
};
function resetTime() {
clearInterval(myInterval);
remainSec = workTime * 60;
startWork();
}
function decreaseWork() {
if (workTime >= 1) {
document.getElementById('workTime').innerHTML = --workTime;
remainSec = workTime * 60;
}
}
function decreaseBreak() {
if (breakTime >= 1) {
document.getElementById('breakTime').innerHTML = --breakTime;
}
}
function increaseWork() {
document.getElementById('workTime').innerHTML = ++workTime;
remainSec = workTime * 60;
}
function increaseBreak() {
document.getElementById('breakTime').innerHTML = ++breakTime;
}
document.getElementById('start').addEventListener('click', startWork);
document.getElementById('pause').addEventListener('click', pauseTime);
document.getElementById('reset').addEventListener('click', resetTime);
document.getElementById('decreaseWork').addEventListener('click', decreaseWork);
document.getElementById('decreaseBreak').addEventListener('click', decreaseBreak);
document.getElementById('increaseWork').addEventListener('click', increaseWork);
document.getElementById('increaseBreak').addEventListener('click', increaseBreak);
Any feedback is much appreciated!
I just added a few things.
First two flags were added to know if isPomodoroTime status and if isBreakTime status, maybe you ask why two? because I needed a initial state which is when both were false, with those flags I can incremente and display time without confusing, for that there is a new function callled changeTimeAndDisplay that is being called from all increase and decrease methods. I also put a startWork in the callback where suppose to be called when break time finish.
here is a demo - codepen.io
var myInterval;
var workTime = document.getElementById("workTime").innerHTML = 25;
var breakTime = document.getElementById("breakTime").innerHTML = 5;
var remainSec = workTime * 60;
var isPomodoroTime = false; //new
var isBreakTime = false; //new
//new function
function changeTimeAndDisplay(newTime){
remainSec = newTime * 60;
displayTime(remainSec);
}
document.getElementById("display").innerHTML = workTime;
function startWork() {
isPomodoroTime = true; //new
document.getElementById("start").disabled = true;
timer(callback);
}
function pauseTime() {
clearInterval(myInterval);
document.getElementById("start").disabled = false;
}
function displayTime(remainingTime) {
if (remainingTime % 60 >= 10) {
document.getElementById('display').innerHTML = Math.floor(remainingTime / 60) + ':' + Math.floor(remainingTime % 60);
} else {
document.getElementById('display').innerHTML = Math.floor(remainingTime / 60) + ':' + "0" + Math.floor(remainingTime % 60);
}
}
function timer(pomodoro) {
var remainingTime = remainSec;
myInterval = setTimeout(function() {
displayTime(remainingTime);
if (remainingTime >= 0) {
remainSec--;
timer(pomodoro);
} else {
clearInterval(myInterval); //new
pomodoro();
}
}, 1000);
}
var callback = function() {
isPomodoroTime = false; //new
isBreakTime = true; //new
console.log('callback');
document.getElementById('timerStatus').innerHTML = "Take a break!";
remainSec = breakTime * 60;
timer(callbackRest)
};
var callbackRest = function() {
isPomodoroTime = true; //new
isBreakTime = false; //new
clearInterval(myInterval);
console.log('callbackRest');
document.getElementById('timerStatus').innerHTML = "Begin";
remainSec = workTime * 60;
document.getElementById("start").disabled = false;
startWork(); //new
};
function resetTime() {
clearInterval(myInterval);
remainSec = workTime * 60;
startWork();
}
function decreaseWork() {
if (workTime >= 1) {
document.getElementById('workTime').innerHTML = --workTime;
if(isPomodoroTime || !isPomodoroTime && !isBreakTime){ //new if block
changeTimeAndDisplay(workTime);
}
}
}
function decreaseBreak() {
if (breakTime >= 1) {
document.getElementById('breakTime').innerHTML = --breakTime;
if(!isPomodoroTime && isBreakTime){ //new if block
changeTimeAndDisplay(breakTime);
}
}
}
function increaseWork() {
document.getElementById('workTime').innerHTML = ++workTime;
if(isPomodoroTime || !isPomodoroTime && !isBreakTime){ //new if block
changeTimeAndDisplay(workTime);
}
}
function increaseBreak() {
document.getElementById('breakTime').innerHTML = ++breakTime;
if(!isPomodoroTime && isBreakTime){ //new if block
changeTimeAndDisplay(breakTime);
}
}
document.getElementById('start').addEventListener('click', startWork);
document.getElementById('pause').addEventListener('click', pauseTime);
document.getElementById('reset').addEventListener('click', resetTime);
document.getElementById('decreaseWork').addEventListener('click', decreaseWork);
document.getElementById('decreaseBreak').addEventListener('click', decreaseBreak);
document.getElementById('increaseWork').addEventListener('click', increaseWork);
document.getElementById('increaseBreak').addEventListener('click', increaseBreak);
As advice you could simplify more your code for example make a function for document.getElementById(id).addEventListener(evnName,func);
function addAction(evnName,id,selector){
document.getElementById(id).addEventListener(evnName,func);
}
or
function addValue(id,value){
document.getElementById(id).innerHTML = value;
}
And replace all document.getElementById
regards.
Related
I'm trying to prevent my laps from counting the same second. So I'm trying to take the current value and evaluate it as != not equal to the previous value before appending it.
Here is the function, and my HTML. Not sure if I can do anything with the ids I set up. I have jquery set up to run in my javascript, so if you have any ideas with that I would be open to listening. There are a couple of things that probably don't have a use that I have not removed yet.
Javascript Function
let seconds = 0;
let minutes = null;
let hours = null;
let startTimer = null;
let time = null;
let isRunning = (false);
let lapContainer = [];
let x;
let outputseconds;
let outputminutes;
let outputhours;
//connection to button
document.getElementById("start").addEventListener("click", start);
document.getElementById("stop").addEventListener("click", stop);
document.getElementById("reset").addEventListener("click", reset);
document.getElementById("lap").addEventListener("click", lap);
document.getElementById("resetLaps").addEventListener("click", resetLaps);
//functions
function start() {
if (isRunning === false) {
isRunning = true;
//interval
startTimer = setInterval(function () {
seconds++;
if (seconds <= 9) {
outputseconds = "0" + seconds;
document.getElementById("seconds").innerHTML = outputseconds;
} else if (seconds <= 60) {
outputseconds = seconds;
document.getElementById("seconds").innerHTML = outputseconds;
} else if (seconds >= 60) {
minutes++;
outputseconds = "00";
outputminutes = "0" + minutes;
document.getElementById("seconds").innerHTML = outputseconds;
document.getElementById("minutes").innerHTML = outputminutes;
seconds = 0;
} else if (minutes >= 9) {
outputminutes = minutes;
document.getElementById("minutes").innerHTML = outputminutes;
} else if (minutes >= 60) {
hours++;
outputminutes = "00";
outputhours = "0" + hours;
document.getElementById("minutes").innerHTML = outputminutes;
document.getElementById("hours").innerHTML = outputhours;
minutes = 0;
} else if (hours > 9) {
outputhours = hours;
document.getElementById("hours").innerHTML = outputhours;
}
}, 1000); //end of interval
} // end of if check
// should this be seperated out as a function???
let startTime = "00";
if (outputseconds > 0) {
if (outputminutes > 0) {
if (outputhours > 0) {
return outputhours + ":" + outputminutes + ":" + outputseconds;
} else {
return startTime + ":" + outputminutes + ":" + outputseconds;
} // hours
} else {
return startTime + ":" + startTime + ":" + outputseconds;
} //minutes
} else {
return startTime + ":" + startTime + ":" + startTime;
} // end of nested if seconds
} //end of start function
function stop() {
clearInterval(startTimer);
isRunning = false;
}
function reset() {
clearInterval(startTimer);
document.getElementById("seconds").innerHTML = "00";
document.getElementById("minutes").innerHTML = "00";
document.getElementById("hours").innerHTML = "00";
seconds = 0;
minutes = 0;
hours = 0;
isRunning = false;
}
function lap() {
if (isRunning === true) {
//initialize time
let lapTime = start();
//create connection to div
lapContainer = document.getElementById("lapContainer");
// how to check if they equal each other
//create element
const para = document.createElement("p");
//how many laps have been created
let i = document.getElementById("lapContainer").childElementCount;
let index = [i];
//create an index that will add an id to paragraph
para.id = index;
//add the lap to text
para.innerText = lapTime;
let laps = [];
laps = document.getElementById("lapContainer").childNodes[1].textContent;
let lastItem = laps[laps.length - 1];
let currentItem = laps[laps.length];
document.getElementById("test").innerHTML = laps;
if (currentItem !== lastItem) {
lapContainer.appendChild(para);
}
}
}
function resetLaps() {
$(lapContainer).empty();
isRunning = false;
}
HTML
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<title>Stopwatch</title>
<meta name="description" content="A simple stopwatch application" />
<meta name="author" content="****" />
<link rel="icon" href="/favicon.ico" />
<link rel="icon" href="/favicon.svg" type="image/svg+xml" />
<link rel="apple-touch-icon" href="/apple-touch-icon.png" />
<link rel="stylesheet" href="./css/styles.css" />
</head>
<body>
<!-- your content here... -->
<div class="menu">
Timer
Alarm
</div>
<div class="stopwatch-container">
<div class="stopwatch-wrapper">
<div class="stopwatch-button-container">
<button type="button" id="start">START</button>
<button type="button" id="stop">STOP</button>
<button type="button" id="reset">RESET</button>
<button type="button" id="lap">LAP</button>
<button type="button" id="resetLaps">RESET LAPS</button>
</div>
<div class="rectangle-container">
<div class="rectangle">
<p id="textWrapper">
<span id="hours">00</span>:<span id="minutes">00</span>:<span
id="seconds"
>00</span
>
</p>
</div>
</div>
</div>
</div>
<div class="lineBreak"></div>
<div id="lapContainer" class="lap-container"></div>
<p id="test"></p>
<script src="./scripts/scripts.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.6.0/jquery.min.js"></script>
</body>
</html>
Few things you might need to do:
1.When you set the laps array you need to get the array of texts of the all nodes, not just a text of the first node:
//laps = document.getElementById("lapContainer").childNodes[1].textContent;
laps = Array.from(document.getElementById("lapContainer").childNodes).map(node => node.textContent);
2.When you set currentItem you can not use laps[laps.length] because your new value not in the array yet and so it will return undefined. Instead you can just use your lapTime value:
let lastItem = laps[laps.length - 1];
//let currentItem = laps[laps.length];
let currentItem = lapTime;
Example:
let isRunning = Boolean(true);
let lapContainer = [];
document.querySelector('#lap').addEventListener('click', () => lap());
function lap() {
if (isRunning === true) {
//initialize time
let lapTime = start();
//create connection to div
lapContainer = document.getElementById("lapContainer");
// how to check if they equal each other
//create element
const para = document.createElement("p");
//how many laps have been created
let i = document.getElementById("lapContainer").childElementCount;
let index = [i];
//create an index that will add an id to paragraph
para.id = index;
//add the lap to text
para.innerText = lapTime;
let laps = [];
//laps = document.getElementById("lapContainer").childNodes[1].textContent;
laps = Array.from(document.getElementById("lapContainer").childNodes).map(node => node.textContent);
let lastItem = laps[laps.length - 1];
//let currentItem = laps[laps.length];
let currentItem = lapTime;
document.getElementById("test").innerHTML = laps;
if (currentItem !== lastItem) {
lapContainer.appendChild(para);
}
}
}
const start = () => new Date().toString();
<body>
<!-- your content here... -->
<div class="menu">
Timer
Alarm
</div>
<div class="stopwatch-container">
<div class="stopwatch-wrapper">
<div class="stopwatch-button-container">
<button type="button" id="start">START</button>
<button type="button" id="stop">STOP</button>
<button type="button" id="reset">RESET</button>
<button type="button" id="lap">LAP</button>
<button type="button" id="resetLaps">RESET LAPS</button>
</div>
<div class="rectangle-container">
<div class="rectangle">
<p id="textWrapper">
<span id="hours">00</span>:<span id="minutes">00</span>:<span
id="seconds"
>00</span
>
</p>
</div>
</div>
</div>
</div>
<div class="lineBreak"></div>
<div id="lapContainer" class="lap-container"></div>
<p id="test"></p>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.6.0/jquery.min.js"></script>
</body>
The code is creating a responsive page. But every time I press stop and then start again the countdown speeds up. Seconds pass like milliseconds and mins pass like seconds after about 10 or so stops and starts. What might be the issue here?
P.S. I haven't written code for the reset button.
let ms = 0;
let secs = 0;
let mins =0;
let flag = true;
var setIntID;
watchFunction =()=> {
if(flag){
ms +=4 ;
document.getElementById('msecs').innerText = `${ms}`;
if(ms == 1000){
ms =0;
secs++
document.getElementById('secs').innerText = `${secs}:`
if(secs == 60){
mins++;
document.getElementById('min').innerText = `${mins}:`;
secs = 0;
}
}}}
document.getElementById("start").addEventListener('click', function(){
flag = true;
var setIntID = setInterval(watchFunction,1);
console.log(flag) //tracker
})
document.getElementById("stop").addEventListener('click', function(){
flag = false;
console.log(flag); //tracker
clearInterval(setIntID);
})
<div id="mainDiv">
<div>
<span id="min">0:</span>
<span id="secs">0:</span>
<span id="msecs">0</span>
<div>
<button id="start">start</button>
<button id="stop">stop</button>
<button id="reset">reset</button>
</div>
</div>
</div>
You have declared setIntID as a local variable in click for the start button, and therefore it isn't cleared in the click function for the stopbutton.
let ms = 0;
let secs = 0;
let mins =0;
let flag = false;
var setIntID;
watchFunction =()=> {
if(flag){
ms +=4 ;
document.getElementById('msecs').innerText = `${ms}`;
if(ms == 1000){
ms =0;
secs++
document.getElementById('secs').innerText = `${secs}:`
if(secs == 60){
mins++;
document.getElementById('min').innerText = `${mins}:`;
secs = 0;
}
}}}
document.getElementById("start").addEventListener('click', function(){
if (flag) return;
flag = true;
setIntID = setInterval(watchFunction,1);
console.log(flag) //tracker
})
document.getElementById("stop").addEventListener('click', function(){
flag = false;
console.log(flag); //tracker
clearInterval(setIntID);
})
<div id="mainDiv">
<div>
<span id="min">0:</span>
<span id="secs">0:</span>
<span id="msecs">0</span>
<div>
<button id="start">start</button>
<button id="stop">stop</button>
<button id="reset">reset</button>
</div>
</div>
</div>
I think that solves the problem.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<div id="mainDiv">
<div>
<span id="min">0:</span>
<span id="secs">0:</span>
<span id="msecs">0</span>
<div>
<button id="start">start</button>
<button id="stop">stop</button>
<button id="reset">reset</button>
</div>
</div>
</div>
<script>
let ms = 0;
let secs = 0;
let mins =0;
let flag = true;
var setIntID;
var running_instance_count = 0;
watchFunction =()=> {
if(flag){
ms +=4 ;
document.getElementById('msecs').innerText = `${ms}`;
if(ms == 1000){
ms =0;
secs++
document.getElementById('secs').innerText = `${secs}:`
if(secs == 60){
mins++;
document.getElementById('min').innerText = `${mins}:`;
secs = 0;
}
}}}
document.getElementById("start").addEventListener('click', function(){
flag = true;
running_instance_count++;
if(running_instance_count == 1){
setIntID = setInterval(watchFunction,1);}
console.log(flag) //tracker
})
document.getElementById("stop").addEventListener('click', function(){
flag = false;
running_instance_count = 0;
console.log(flag); //tracker
clearInterval(setIntID);
})
document.getElementById('reset').addEventListener('click', function(){
flag = false;
ms=0; secs=0; mins=0;
running_instance_count = 0;
clearInterval(setIntID);
document.getElementById('msecs').innerText = `${0}`;
document.getElementById('secs').innerText = `${0}:`;
document.getElementById('min').innerText = `${0}:`;
})
</script>
</body>
</html>
I see a time boost now, but on it's it's first click it's actually slow at ms +=4 so I changed it to ms +=10. Also, there's no usage of the flag on the event handler which would help control the setInterval() and clearInterval() so that there is only one existing at a time. Everytime the "start" button was clicked in OP code there was another setInterval() added, therefore the time intervals combined accelerated. In the example, there's only one event handler that toggles between setInterval() and clearInterval().
let mil = 0;
let sec = 0;
let min = 0;
let flag = false;
let setIntID;
const form = document.forms.stopWatch;
const fc = form.elements;
const timer = () => {
if (flag) {
fc.milliseconds.value = mil += 10;
if (mil == 1000) {
mil = 0;
sec++;
if (sec < 10) sec = '0' + sec;
fc.seconds.value = sec + ' :';
if (sec == 60) {
min++;
if (min < 10) min = '0' + min;
fc.minutes.value = min + ' :';
sec = 0;
}
}
}
}
fc.toggle.addEventListener('click', function() {
if (!flag) {
flag = true;
setIntID = setInterval(timer, 1);
return
}
clearInterval(setIntID);
flag = false;
});
form.onreset = e => {
mil = 0;
sec = 0;
min = 0;
clearInterval(setIntID);
flag = false;
}
<form id="stopWatch">
<fieldset>
<output id="minutes">00 :</output>
<output id="seconds">00 :</output>
<output id="milliseconds">000</output><br>
<button id="toggle" type='button'>Start/Stop</button>
<button type="reset">Reset</button>
</fieldset>
</form>
I'm trying to get a HTML element, a button, to my javascript file. I've tried .querySelector and .getElementById and my script file is attached at the bottom of my file just before the closing tag of my body element. but for each of variable I've tried the .addListener function on them but receive the error ' Cannot read properties of null (reading 'addEventListener')'
Here is my HTML Code:
<body>
<div class="whole">
<!-- Navbar -->
<div class="logo">
<img src="/focus-logo.png" alt="logo" width="100" height="100">
</div>
<!-- timer -->
<figure class="timer">
<div class="minsSec">
<span class="mins">0</span>
<span>:</span>
<span class="secs">00</span>
</div>
<svg class="progress-ring" height="240" width="240">
<circle
class="progress-ring__circle"
stroke-width="10"
fill="transparent"
r="110"
cx="120"
cy="120"
/>
</svg>
</figure>
<div class="timer__btn">
<button class="set">Set</button>
<button id="start">start focus</button>
<button id="reset">reset</button>
<button class="pause">pause</button>
</div>
<script src="setTime.js"></script>
<script src="newTimer.js"></script>
<script src="progressBar.js"></script>
</div>
</body>
and
<body>
<form action=".">
<label for="focusTime">Focus Time</label>
<input type="number" id="focusTimeNum" />
<label for="breakTime">Break Time</label>
<input type="number" id="breakTime" />
<button type="submit">Save settings</button>
</form>
<script src="setTime.js"></script>
<script src="newTimer.js"></script>
</body>
Newtimer.js
const el = document.querySelector(".timer");
const mindiv = document.querySelector(".mins");
const secdiv = document.querySelector(".secs");
const startBtn = document.querySelector("#start");
localStorage.setItem("btn", "focus");
let initial, totalsecs, perc, paused, mins, seconds;
** startBtn.addEventListener("click", () => { **
let btn = localStorage.getItem("btn");
if (btn === "focus") {
mins = +localStorage.getItem("focusTime") || 1;
} else {
mins = +localStorage.getItem("breakTime") || 1;
}
seconds = mins * 60;
totalsecs = mins * 60;
setTimeout(decremenT(), 60);
startBtn.style.transform = "scale(0)";
paused = false;
});
function decremenT() {
mindiv.textContent = Math.floor(seconds / 60);
secdiv.textConten
t = seconds % 60 > 9 ? seconds % 60 : `0${seconds % 60}`;
if (circle.classList.contains("danger")) {
circle.classList.remove("danger");
}
if (seconds > 0) {
perc = Math.ceil(((totalsecs - seconds) / totalsecs) * 100);
setProgress(perc);
seconds--;
initial = window.setTimeout("decremenT()", 1000);
if (seconds < 10) {
circle.classList.add("danger");
}
} else {
mins = 0;
seconds = 0;
let btn = localStorage.getItem("btn");
if (btn === "focus") {
startBtn.textContent = "start break";
startBtn.classList.add("break");
localStorage.setItem("btn", "break");
} else {
startBtn.classList.remove("break");
startBtn.textContent = "start focus";
localStorage.setItem("btn", "focus");
}
startBtn.style.transform = "scale(1)";
}
}
and setTimer.js
const focusTimeInput = document.getElementById("focusTimeNum").value;
const breakTimeInput = document.querySelector("#breakTime");
const pauseBtn = document.querySelector(".pause");
focusTimeInput.value = localStorage.getItem("focusTime");
breakTimeInput.value = localStorage.getItem("breakTime");
document.querySelector("form").addEventListener("submit", (e) => {
e.preventDefault();
localStorage.setItem("focusTime", focusTimeInput.value);
localStorage.setItem("breakTime", breakTimeInput.value);
});
document.getElementById("reset").addEventListener("click", () => {
startBtn.style.transform = "scale(1)";
clearTimeout(initial);
setProgress(0);
mindiv.textContent = 0;
secdiv.textContent = 0;
});
pauseBtn.addEventListener("click", () => {
if (paused === undefined) {
return;
}
if (paused) {
paused = false;
initial = setTimeout("decremenT()", 60);
pauseBtn.textContent = "pause";
pauseBtn.classList.remove("resume");
} else {
clearTimeout(initial);
pauseBtn.textContent = "resume";
pauseBtn.classList.add("resume");
paused = true;
}
});
The line from newTimer.js
startBtn.addEventListener("click", () => {
and the line from setTimer.js
document.getElementById("reset").addEventListener("click", () => {
I'm using node and express for the backend side
I've been trying to add a simple stopwatch to my Rails app, and I've adapted the one I found here: https://jsfiddle.net/waqasumer/agru2bdL/
The code seems to work in the console (the timer starts and stops), but I'm getting this error when using the controls and the UI is not showing the stopwatch (it's just reading zero):
Uncaught TypeError: Cannot set property 'innerHTML' of null
Any help to get this working would be appreciated. I've included my code below.
var min = 0;
var sec = 0;
var msec = 0;
var getMin = document.getElementById("min");
var getSec = document.getElementById("sec");
var getmsec = document.getElementById("msec");
var interval;
function timer() {
msec++
getmsec.innerHTML = msec;
if (msec >= 100) {
sec++;
if (sec <= 9) {
getSec.innerHTML = "0" + sec;
} else {
getSec.innerHTML = sec;
}
msec = 0;
} else if (sec >= 60) {
min++;
if (min <= 9) {
getMin.innerHTML = "0" + min;
} else {
getMin.innerHTML = min;
}
sec = 0;
}
}
function start() {
interval = setInterval(timer, 10);
var btn = document.getElementById("start");
btn.disabled = true;
}
function stop() {
clearInterval(interval);
var btn = document.getElementById("start");
btn.disabled = false;
}
function reset() {
min = "00";
sec = "00";
msec = "00";
getMin.innerHTML = min;
getSec.innerHTML = sec;
getmsec.innerHTML = msec;
clearInterval(interval);
}
function lapTimer() {
var Laps = document.getElementById('laps');
Laps.innerHTML += "<div>" + " " + getMin.innerHTML + ":" + getSec.innerHTML + ":" + getmsec.innerHTML + "</div>";
}
<h1 class="title">Stopwatch</h1>
<div class="stopwatch">
<div class="circle">
<div class="time"><span id="min">00</span>:<span id="sec">00</span>:<span id="msec">00</span></div>
</div>
<div class="controls">
<button id="start" onclick="start()" type="button"><img class="controls-img" id="playButton" src="<%= asset_path( 'play_button.png' ) %>" /></button>
<button onclick="stop()" type="button"><img class="controls-img" id="pauseButton" src="<%= asset_path( 'pause_button.png' ) %>" /></button>
<button onclick="lapTimer()" id="lapButton" type="button"><img class="controls-img" id="pauseButton" src="<%= asset_path( 'lap.png' ) %>" /></button>
<button onclick="reset()" type="button"><img class="controls-img" id="pauseButton" src="<%= asset_path( 'reset_button.png' ) %>" />
</button>
</div>
</div>
<br>
<div class="row" id="laps"></div>
The js code will executed, before the page is ready. You have 2 solutions. Put your js code at the end of the page or look here $(document).ready equivalent without jQuery
i have no idea how to save and show out put next to stopwatch:
00:01:30 , 00:01:30 something like this.
its not important but can i make stopwatch to stop on some time like 45 min
i created a button "save" was playing whit code but i have no idea how to make it save output and show
i was trying to find in internet but could not find
I appreciate any help.
var ss = document.getElementsByClassName('stopwatch');
[].forEach.call(ss, function(s) {
var currentTimer = 0,
interval = 0,
lastUpdateTime = new Date().getTime(),
start = s.querySelector('button.start'),
stop = s.querySelector('button.stop'),
reset = s.querySelector('button.reset'),
mins = s.querySelector('span.minutes'),
secs = s.querySelector('span.seconds'),
cents = s.querySelector('span.centiseconds');
start.addEventListener('click', startTimer);
stop.addEventListener('click', stopTimer);
reset.addEventListener('click', resetTimer);
function pad(n) {
return ('00' + n).substr(-2);
}
function update() {
var now = new Date().getTime(),
dt = now - lastUpdateTime;
currentTimer += dt;
var time = new Date(currentTimer);
mins.innerHTML = pad(time.getMinutes());
secs.innerHTML = pad(time.getSeconds());
cents.innerHTML = pad(Math.floor(time.getMilliseconds() / 10));
lastUpdateTime = now;
}
function startTimer() {
if (!interval) {
lastUpdateTime = new Date().getTime();
interval = setInterval(update, 1);
}
}
function stopTimer() {
clearInterval(interval);
interval = 0;
}
function resetTimer() {
stopTimer();
currentTimer = 0;
mins.innerHTML = secs.innerHTML = cents.innerHTML = pad(0);
}
});
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Stopwatch</title>
</head>
<body>
<h1>Stopwatch</h1>
<div class="stopwatch">
<div class="controls">
<button class="start">Start</button>
<button class="stop">Stop</button>
<button class="reset">Reset</button>
<button class="save">save</button>
</div>
<div class="display">
<span class="minutes">00</span>:<span class="seconds">00</span>:<span class="centiseconds">00</span>
</div>
</div>
<script src="stopwatch.js"></script>
</body>
</html>
if i correct understand - here is solution. You still need some validations on input fields, checks on current timer and ithers, but it's worked version if user takes into account all these nuances himself.
index.html
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title>Stopwatch</title>
</head>
<body>
<h1>Stopwatch</h1>
<div class="stopwatch">
<div class="controls">
<button class="start">Start</button>
<button class="stop">Stop</button>
<button class="reset">Reset</button>
||stop on:
<input class="min" placeholder="min" type="text" style="width: 30px" />:
<input class="sec" placeholder="sec" type="text" style="width: 30px" />:
<input class="ms" placeholder="ms" type="text" style="width: 30px" />
<button class="save">save</button>
<div class="savedTimeBlock" style="display: none">
saved time:
<div style="display: inline-block" class="time"></div>
</div>
</div>
<div class="display">
<span class="minutes">00</span>:<span class="seconds">00</span>:<span
class="centiseconds"
>00</span
>
</div>
</div>
<script src="stopwatch.js"></script>
</body>
</html>
stopwatch.js
var ss = document.getElementsByClassName("stopwatch");
[].forEach.call(ss, function(s) {
var currentTimer = 0,
interval = 0,
lastUpdateTime = new Date().getTime(),
timeToStop = {
min:null,
sec:null,
ms:null
},
start = s.querySelector("button.start"),
stop = s.querySelector("button.stop"),
reset = s.querySelector("button.reset"),
mins = s.querySelector("span.minutes"),
secs = s.querySelector("span.seconds"),
cents = s.querySelector("span.centiseconds"),
minutes = s.querySelector(".min"),
seconds = s.querySelector(".sec"),
milliseconds = s.querySelector(".ms"),
savedTimeBlock = s.querySelector(".savedTimeBlock"),
time = s.querySelector(".time"),
save = s.querySelector(".save");
start.addEventListener("click", startTimer);
stop.addEventListener("click", stopTimer);
save.addEventListener("click", saveStopTime);
reset.addEventListener("click", resetTimer);
function pad(n) {
return ("00" + n).substr(-2);
}
function saveStopTime() {
let min = timeToStop.min = pad(+minutes.value),
sec = timeToStop.sec = pad(+seconds.value),
ms = timeToStop.ms = pad(+milliseconds.value);
if (+min || +sec || +ms) {
showSavedTimeBlock(min, sec, ms)
} else {
killSavedTimeBlock()
}
}
const showSavedTimeBlock = (min, sec, ms) => {
savedTimeBlock.style.display = 'inline-block';
time.innerText = `${min}:${sec}:${ms}:`
};
const killSavedTimeBlock = () => {
savedTimeBlock.style.display = 'none';
timeToStop.min = null;
timeToStop.sec = null;
timeToStop.ms = null;
time.innerText = ''
};
function update() {
var now = new Date().getTime(),
dt = now - lastUpdateTime;
currentTimer += dt;
var time = new Date(currentTimer);
let min = pad(time.getMinutes());
let sec = pad(time.getSeconds());
let ms = pad(Math.floor(time.getMilliseconds() / 10));
mins.innerHTML = min;
secs.innerHTML = sec;
cents.innerHTML = ms;
let ts = timeToStop;
if (ts.min === min && ts.sec === sec && ts.ms === ms) {
stopTimer()
} else {
lastUpdateTime = now;
}
}
function startTimer() {
if (!interval) {
lastUpdateTime = new Date().getTime();
interval = setInterval(update, 1);
}
}
function stopTimer() {
clearInterval(interval);
interval = 0;
}
function resetTimer() {
stopTimer();
killSavedTimeBlock()
currentTimer = 0;
mins.innerHTML = secs.innerHTML = cents.innerHTML = pad(0);
}
});