Reputation: 1341
i have this stopwatch code below which runs on SS:MS(seconds.milliseconds) format at first, and i want it to run on MM:SS.MS(minutes:seconds.milliseconds) format when it reaches above 60 seconds, here is my code
let sec = 0;
let min = 0;
let millisecond = 0;
const stopwatch = document.getElementById("stopwatch");
function stopwatchStart() {
sec = parseInt(sec);
min = parseInt(min);
millisecond = parseInt(millisecond);
millisecond = millisecond + 1;
if (millisecond == 100) {
sec = sec + 1;
millisecond = 0;
}
stopwatch.innerHTML = sec + '.' + millisecond;
if (sec === 60) {
min = min + 1;
sec = 0;
// how do i make it run on MM:SS:MS format
};
setTimeout("stopwatchStart()", 10);
}
i tried this code but does not work (doesnt change the innerHTML of stopwatch)
if (sec === 60) {
min = min + 1;
sec = 0;
stopwatch.innerHTML = min + ":" + sec + "." + millisecond;
};
Upvotes: 0
Views: 630
Reputation: 1280
function initStopWatch(hh, mm, ss, fff) {
hh = +hh || 0;
mm = +mm || 0;
ss = +ss || 0;
fff = +fff || 0;
var timer = null, on = {
hour: function (h) { },
minute: function (m) { },
second: function (s) { },
milliSecond: function (f) { }
}, last = 0, now = 0;
function run() {
now = Date.now();
fff += (now - last);
last = now;
if (fff > 999) {
fff -= 1000;
ss++;
if (ss > 59) {
ss -= 60;
mm++;
if (mm > 59) {
mm -= 60;
hh++;
on.hour(hh);
}
on.minute(mm);
}
on.second(ss);
}
on.milliSecond(fff);
}
function start() {
stop();
last = now = Date.now();
timer = setInterval(run, 10);
}
function stop() {
clearInterval(timer);
}
function reset() {
stop();
hh = mm = ss = fff = last = now = 0;
on.hour(hh);
on.minute(mm);
on.second(ss);
on.milliSecond(fff);
}
return { start, stop, reset, on };
}
window.onload = function () {
var hhElement = document.querySelector('.swatch .hh'),
mmElement = document.querySelector('.swatch .mm'),
ssElement = document.querySelector('.swatch .ss'),
fffElement = document.querySelector('.swatch .fff');
var stopWatch = initStopWatch();
stopWatch.on.hour = function (h) {
hhElement.textContent = (h + "").padStart(2, "0");
}
stopWatch.on.minute = function (m) {
mmElement.textContent = (m + "").padStart(2, "0");
}
stopWatch.on.second = function (s) {
ssElement.textContent = (s + "").padStart(2, "0");
}
stopWatch.on.milliSecond = function (f) {
fffElement.textContent = (f + "").padStart(3, "0");
}
document.querySelector('.swatch').addEventListener('click', function (e) {
var cls = e.target.classList;
if (cls.contains('start')) {
stopWatch.start();
e.target.textContent = "Stop";
cls.remove('start');
cls.add('stop');
} else if (cls.contains('stop')) {
stopWatch.stop();
e.target.textContent = "Start";
cls.remove('stop');
cls.add('start');
} else if (cls.contains('reset')) {
stopWatch.reset();
var stopBtnElement = e.currentTarget.querySelector('.stop');
if (stopBtnElement) {
var cls2 = stopBtnElement.classList;
stopBtnElement.textContent = "Start";
cls2.remove('stop');
cls2.add('start');
}
}
});
}
.swatch {
font-size: 32pt;
font-weight: bold;
color: green;
font-family: Comic Sans MS, Comic Sans, cursive;
}
.swatch .fff {
font-size: 24pt;
}
.swatch button {
min-width: 100px;
font-size: 12pt;
padding: 10px;
background-color: green;
color: white;
font-weight: bold;
}
.swatch button:hover {
background-color: darkgreen;
}
<div class="swatch">
<div>
<span class="hh">00</span> :
<span class="mm">00</span> :
<span class="ss">00</span> .
<span class="fff">000</span>
</div>
<div>
<button type="button" class='start'>Start</button>
<button type="button" class='reset'>Reset</button>
</div>
</div>
Upvotes: 1
Reputation: 1463
You shouldn't trust setTimeout in this way, as you can never know when it will run. Easier method is to keep the starting datetime in a variable and make a difference from that. Even if there is a delay, your timer remains correct.
Using Intl.DateTimeFormat
for formatting and setInterval
instead of setTimeout
also helps.
let startDate,
interval = null,
stopwatch = document.getElementById("stopwatch"),
btn = document.getElementById("btn"),
dateTimeFormat = new Intl.DateTimeFormat('default', {
minute: 'numeric',
second: 'numeric',
fractionalSecondDigits: 2});
function startStopWatch(){
if(interval === null){
startDate = Date.now();
displayStopWatch();
stopwatch.innerHTML= "test";
interval = setInterval(displayStopWatch, 10);
} else {
clearInterval(interval);
interval = null;
}
}
function displayStopWatch(){
let diff = Date.now() - startDate;
stopwatch.innerHTML= dateTimeFormat.format(new Date(diff));
}
btn.addEventListener('click', function() {
startStopWatch();
});
<button id="btn">start/stop</button>
<div id ="stopwatch">
</div>
Upvotes: 2