Reputation: 86
I'm trying to make a very simple stopwatch, but I cannot make 'pause' works properly. It should pause the stopwatch and after clicking 'START' again - proceed the timer. But it just stopps and resets the timer
var body = document.body;
var start = document.querySelector('.start');
var stop = document.querySelector('.stop');
var reset = document.querySelector('.reset');
var lap = document.querySelector('.lap');
var lapContainer = document.querySelector('.lapContainer');
var mil = document.querySelector('.milis');
var sec = document.querySelector('.secs');
var min = document.querySelector('.mins');
var hours = document.querySelector('.hours');
var flag = false;
// Create blocks for time markers
function createTimeSection(timeType) { // timeType = min/sec/ms/ :
var lapTime = document.createElement('div');
lapTime.classList.add('lapSection');
lapBlock.appendChild(lapTime);
lapTime.innerHTML = (timeType);
}
function createTimeBlock(type) {
lapBlock = document.createElement('div');
lapBlock.classList.add('lapBlock');
lapContainer.appendChild(lapBlock);
var lapText = document.createElement('div');
lapText.classList.add('lapText');
lapBlock.appendChild(lapText);
lapText.innerHTML = (type);
createTimeSection(hours);
createTimeSection(':');
createTimeSection(minutes);
createTimeSection(':');
createTimeSection(seconds);
createTimeSection(':');
createTimeSection(milliseconds);
}
// hide/display START/STOP buttons
function displayStopButton() {
start.style.display = 'none';
stop.style.display = 'block';
}
function displayStartButton() {
start.style.display = 'block';
stop.style.display = 'none';
}
// Get Date start point
function startStopwatch() {
flag = true;
initialDate = new Date;
}
// calculate timer
function getTime() {
var currentDate = new Date;
timer = new Date (currentDate - initialDate);
milliseconds = timer.getMilliseconds();
seconds = timer.getSeconds();
minutes = timer.getMinutes();
hours = timer.getUTCHours();
if(milliseconds < 100){
milliseconds = '0' + milliseconds;
}
if(seconds < 10){
seconds = '0' + seconds;
}
if (minutes < 10){
minutes = '0' + minutes;
}
if (hours < 10){
hours = '0' + hours;
}
}
// display timer in document
function counter() {
getTime();
mil.innerHTML = milliseconds;
sec.innerHTML = seconds;
min.innerHTML = minutes;
hours.innerHTML = hours;
}
// interval for display
function displayTimer() {
timerId = setInterval(counter, 10);
}
function stopTimer() {
clearInterval(timerId);
getTime();
createTimeBlock('STOP');
flag = false;
}
function newLap() {
if (flag == true){
getTime();
createTimeBlock('LAP');
} else {
lapBlock = document.createElement('div');
lapBlock.classList.add('lapBlock');
lapContainer.appendChild(lapBlock);
var lapText = document.createElement('div');
lapText.classList.add('lapText');
lapBlock.appendChild(lapText);
lapText.innerHTML = ('PRESS START FIRST');
}
}
function resetTimer() {
flag = false;
clearInterval(timerId);
start.style.display = 'block';
stop.style.display = 'none';
mil.innerHTML = '00';
min.innerHTML = '00';
sec.innerHTML = '00';
document.querySelector('.lapContainer').innerHTML = '';
}
start.addEventListener('click', startStopwatch);
start.addEventListener('click', displayStopButton);
start.addEventListener('click', displayTimer);
lap.addEventListener('click', newLap)
stop.addEventListener('click', stopTimer)
stop.addEventListener('click', displayStartButton);
reset.addEventListener('click', resetTimer);
.top-block{
position: fixed;
left: 150px;
}
.sw{
float: left;
width: 100px;
height: 30px;
border: 1px solid black;
margin: 10px;
text-align: center;
}
.buttons-block{
clear: both;
}
.button{
margin: 10px;
float: left;
display: block;
width: 100px;
height: 30px;
color: black;
font-weight: bold;
font-size: 20px;
text-decoration: none;
text-align: center;
line-height: 30px;
border: 1px solid black;
}
.start{
background: green;
clear: both;
}
.stop{
display: none;
background: yellow;
}
.reset{
background: #6b919c;
}
.lap{
background: rgb(120,120,120);
}
.hours,
.secs,
.mins,
.milis{
margin: 0;
line-height: 32px;
}
.lapBlock{
clear: both;
height: 30px;
width: 280px;
}
.lapSection{
float: left;
margin: 1px;
}
.lapText{
float: left;
margin-right: 5px;
}
.lapContainer{
float: left;
margin-top: 15px;
}
<div class="top-block">
<div class="sw">
<p class="hours">00</p>
</div>
<div class="sw">
<p class="mins">00</p>
</div>
<div class="sw">
<p class="secs">00</p>
</div>
<div class="sw">
<p class="milis">00</p>
</div>
<div class="buttons-block">
<a href="#" class="button start">START</a>
<a href="#" class="button stop">PAUSE</a>
<a href="#" class="button lap">LAP</a>
<a href="#" class="button reset">RESET</a>
</div>
</div>
<div class="lapContainer">
</div>
Upvotes: 0
Views: 101
Reputation: 780818
You need to distinguish the first click on Start
, which should start counting from 0, with subsequent clicks. You can use a variable that's set by the Reset
button. In my code this is the first_time
variable.
When you pause the stopwatch, you need to save the current time. Then when you restart it, adjust initialDate
by the difference in time since it was paused.
// Get Date start point
function startStopwatch() {
flag = true;
if (first_time) {
initialDate = new Date;
first_time = false;
} else {
initialDate.setMilliseconds(initialDate.getMilliseconds() + (new Date - pauseTime));
}
}
var body = document.body;
var start = document.querySelector('.start');
var stop = document.querySelector('.stop');
var reset = document.querySelector('.reset');
var lap = document.querySelector('.lap');
var lapContainer = document.querySelector('.lapContainer');
var mil = document.querySelector('.milis');
var sec = document.querySelector('.secs');
var min = document.querySelector('.mins');
var hours = document.querySelector('.hours');
var flag = false;
var first_time = true;
// Create blocks for time markers
function createTimeSection(timeType) { // timeType = min/sec/ms/ :
var lapTime = document.createElement('div');
lapTime.classList.add('lapSection');
lapBlock.appendChild(lapTime);
lapTime.innerHTML = (timeType);
}
function createTimeBlock(type) {
lapBlock = document.createElement('div');
lapBlock.classList.add('lapBlock');
lapContainer.appendChild(lapBlock);
var lapText = document.createElement('div');
lapText.classList.add('lapText');
lapBlock.appendChild(lapText);
lapText.innerHTML = (type);
createTimeSection(hours);
createTimeSection(':');
createTimeSection(minutes);
createTimeSection(':');
createTimeSection(seconds);
createTimeSection(':');
createTimeSection(milliseconds);
}
// hide/display START/STOP buttons
function displayStopButton() {
start.style.display = 'none';
stop.style.display = 'block';
}
function displayStartButton() {
start.style.display = 'block';
stop.style.display = 'none';
}
// Get Date start point
function startStopwatch() {
flag = true;
if (first_time) {
initialDate = new Date;
first_time = false;
} else {
initialDate.setMilliseconds(initialDate.getMilliseconds() + (new Date - pauseTime));
}
}
// calculate timer
function getTime() {
var currentDate = new Date;
timer = new Date (currentDate - initialDate);
milliseconds = timer.getMilliseconds();
seconds = timer.getSeconds();
minutes = timer.getMinutes();
hours = timer.getUTCHours();
if(milliseconds < 100){
milliseconds = '0' + milliseconds;
}
if(seconds < 10){
seconds = '0' + seconds;
}
if (minutes < 10){
minutes = '0' + minutes;
}
if (hours < 10){
hours = '0' + hours;
}
}
// display timer in document
function counter() {
getTime();
mil.innerHTML = milliseconds;
sec.innerHTML = seconds;
min.innerHTML = minutes;
hours.innerHTML = hours;
}
// interval for display
function displayTimer() {
timerId = setInterval(counter, 10);
}
function stopTimer() {
clearInterval(timerId);
getTime();
createTimeBlock('STOP');
flag = false;
pauseTime = new Date;
}
function newLap() {
if (flag == true){
getTime();
createTimeBlock('LAP');
} else {
lapBlock = document.createElement('div');
lapBlock.classList.add('lapBlock');
lapContainer.appendChild(lapBlock);
var lapText = document.createElement('div');
lapText.classList.add('lapText');
lapBlock.appendChild(lapText);
lapText.innerHTML = ('PRESS START FIRST');
}
}
function resetTimer() {
flag = false;
first_time = true;
clearInterval(timerId);
start.style.display = 'block';
stop.style.display = 'none';
mil.innerHTML = '00';
min.innerHTML = '00';
sec.innerHTML = '00';
document.querySelector('.lapContainer').innerHTML = '';
}
start.addEventListener('click', startStopwatch);
start.addEventListener('click', displayStopButton);
start.addEventListener('click', displayTimer);
lap.addEventListener('click', newLap)
stop.addEventListener('click', stopTimer)
stop.addEventListener('click', displayStartButton);
reset.addEventListener('click', resetTimer);
.top-block{
position: fixed;
left: 150px;
}
.sw{
float: left;
width: 100px;
height: 30px;
border: 1px solid black;
margin: 10px;
text-align: center;
}
.buttons-block{
clear: both;
}
.button{
margin: 10px;
float: left;
display: block;
width: 100px;
height: 30px;
color: black;
font-weight: bold;
font-size: 20px;
text-decoration: none;
text-align: center;
line-height: 30px;
border: 1px solid black;
}
.start{
background: green;
clear: both;
}
.stop{
display: none;
background: yellow;
}
.reset{
background: #6b919c;
}
.lap{
background: rgb(120,120,120);
}
.hours,
.secs,
.mins,
.milis{
margin: 0;
line-height: 32px;
}
.lapBlock{
clear: both;
height: 30px;
width: 280px;
}
.lapSection{
float: left;
margin: 1px;
}
.lapText{
float: left;
margin-right: 5px;
}
.lapContainer{
float: left;
margin-top: 15px;
}
<div class="top-block">
<div class="sw">
<p class="hours">00</p>
</div>
<div class="sw">
<p class="mins">00</p>
</div>
<div class="sw">
<p class="secs">00</p>
</div>
<div class="sw">
<p class="milis">00</p>
</div>
<div class="buttons-block">
<a href="#" class="button start">START</a>
<a href="#" class="button stop">PAUSE</a>
<a href="#" class="button lap">LAP</a>
<a href="#" class="button reset">RESET</a>
</div>
</div>
<div class="lapContainer">
</div>
Another option would be to have separate Start
and Resume
buttons. The Start
button would initialize initialDate
, but the Resume
button wouldn't.
Clicking the Pause
button shows the Resume
button, while clicking Reset
shows the Start
button.
Upvotes: 0
Reputation: 18995
You should reset date only upon reset of the timer, but you also do it once the timer is paused.
To do this, I've moved the date initialization to the beginning and also applied it on reset.
Also, your timer was continuing to tick even if stopped, to avoid this I'm just counting stop offset and applying it to the date:
setInterval(function(){
if(flag==false) offset+=10;
},10)
initialDate = new Date;
var body = document.body;
var start = document.querySelector('.start');
var stop = document.querySelector('.stop');
var reset = document.querySelector('.reset');
var lap = document.querySelector('.lap');
var lapContainer = document.querySelector('.lapContainer');
var mil = document.querySelector('.milis');
var sec = document.querySelector('.secs');
var min = document.querySelector('.mins');
var hours = document.querySelector('.hours');
var flag = false;
var waitTimer, offset=0;
// Create blocks for time markers
function createTimeSection(timeType) { // timeType = min/sec/ms/ :
var lapTime = document.createElement('div');
lapTime.classList.add('lapSection');
lapBlock.appendChild(lapTime);
lapTime.innerHTML = (timeType);
}
function createTimeBlock(type) {
lapBlock = document.createElement('div');
lapBlock.classList.add('lapBlock');
lapContainer.appendChild(lapBlock);
var lapText = document.createElement('div');
lapText.classList.add('lapText');
lapBlock.appendChild(lapText);
lapText.innerHTML = (type);
createTimeSection(hours);
createTimeSection(':');
createTimeSection(minutes);
createTimeSection(':');
createTimeSection(seconds);
createTimeSection(':');
createTimeSection(milliseconds);
}
// hide/display START/STOP buttons
function displayStopButton() {
start.style.display = 'none';
stop.style.display = 'block';
}
function displayStartButton() {
start.style.display = 'block';
stop.style.display = 'none';
}
// Get Date start point
function startStopwatch() {
flag = true;
}
setInterval(function(){
if(flag==false) offset+=10;
},10)
// calculate timer
function getTime() {
var currentDate = new Date;
timer = new Date (currentDate - initialDate - offset);
milliseconds = timer.getMilliseconds();
seconds = timer.getSeconds();
minutes = timer.getMinutes();
hours = timer.getUTCHours();
if(milliseconds < 100){
milliseconds = '0' + milliseconds;
}
if(seconds < 10){
seconds = '0' + seconds;
}
if (minutes < 10){
minutes = '0' + minutes;
}
if (hours < 10){
hours = '0' + hours;
}
}
// display timer in document
function counter() {
getTime();
mil.innerHTML = milliseconds;
sec.innerHTML = seconds;
min.innerHTML = minutes;
hours.innerHTML = hours;
}
// interval for display
function displayTimer() {
timerId = setInterval(counter, 10);
}
function stopTimer() {
clearInterval(timerId);
getTime();
createTimeBlock('STOP');
flag = false;
}
function newLap() {
if (flag == true){
getTime();
createTimeBlock('LAP');
} else {
lapBlock = document.createElement('div');
lapBlock.classList.add('lapBlock');
lapContainer.appendChild(lapBlock);
var lapText = document.createElement('div');
lapText.classList.add('lapText');
lapBlock.appendChild(lapText);
lapText.innerHTML = ('PRESS START FIRST');
}
}
function resetTimer() {
initialDate = new Date;
flag = false;
offset=0;
clearInterval(timerId);
start.style.display = 'block';
stop.style.display = 'none';
mil.innerHTML = '00';
min.innerHTML = '00';
sec.innerHTML = '00';
document.querySelector('.lapContainer').innerHTML = '';
}
start.addEventListener('click', startStopwatch);
start.addEventListener('click', displayStopButton);
start.addEventListener('click', displayTimer);
lap.addEventListener('click', newLap)
stop.addEventListener('click', stopTimer)
stop.addEventListener('click', displayStartButton);
reset.addEventListener('click', resetTimer);
.top-block{
position: fixed;
left: 150px;
}
.sw{
float: left;
width: 100px;
height: 30px;
border: 1px solid black;
margin: 10px;
text-align: center;
}
.buttons-block{
clear: both;
}
.button{
margin: 10px;
float: left;
display: block;
width: 100px;
height: 30px;
color: black;
font-weight: bold;
font-size: 20px;
text-decoration: none;
text-align: center;
line-height: 30px;
border: 1px solid black;
}
.start{
background: green;
clear: both;
}
.stop{
display: none;
background: yellow;
}
.reset{
background: #6b919c;
}
.lap{
background: rgb(120,120,120);
}
.hours,
.secs,
.mins,
.milis{
margin: 0;
line-height: 32px;
}
.lapBlock{
clear: both;
height: 30px;
width: 280px;
}
.lapSection{
float: left;
margin: 1px;
}
.lapText{
float: left;
margin-right: 5px;
}
.lapContainer{
float: left;
margin-top: 15px;
}
<div class="top-block">
<div class="sw">
<p class="hours">00</p>
</div>
<div class="sw">
<p class="mins">00</p>
</div>
<div class="sw">
<p class="secs">00</p>
</div>
<div class="sw">
<p class="milis">00</p>
</div>
<div class="buttons-block">
<a href="#" class="button start">START</a>
<a href="#" class="button stop">PAUSE</a>
<a href="#" class="button lap">LAP</a>
<a href="#" class="button reset">RESET</a>
</div>
</div>
<div class="lapContainer">
</div>
Upvotes: 1