I have some code for a stopwatch here: https://github.com/Aerodyll/Stopwatch
As you can see the counter changes the html of 4 tags for hours, minutes, seconds and milliseconds. And it ties to 3 buttons, start, stop and clear.
This works fine when there is just one counter on screen but how would I alter this code to make it work for multiple counters on the screen at once (that all work independently)? It just breaks when I duplicate it at the moment. I understand why it breaks because it is pointing to the same html objects but how would I go about duplicating the counters on the page without writing a whole new script for each one?
(I have found a couple of examples of other users doing this but their code is very difficult for me to understand.)
works fine when there is just one counter on screen but how would I alter this code to make it work for multiple counters on the screen at once ...
div
to create multiple blocks. Give this wrapper an id
if you want to target those individually. Alternatively, just give it a same class
if you want to target them all.id
or element itself.span
s within the element. This could be done via class
or nth-child
selector. Example:
The example below is your original code, just refactored as per the above points.
var allWatches = document.getElementsByClassName('stopwatch'),
firstWatch = document.getElementById('sw1')
;
// One way to call stopwatch on individual blocks
//stopWatch('sw1'); // pass id to the function
// Another way to call stopwatch on individual blocks
//stopWatch(firstWatch); // pass the element ref to the function
// One way to call stopwatch on all blocks
for(i=0; i < allWatches.length; i++) {
stopWatch(allWatches[i]);
}
function stopWatch(element) {
/* Declaring the html objects that will contain the time */
var hrs, mins, secs;
/* Declaring the html buttons */
var start, stop, clear;
/* Other variables */
var seconds = 0, minutes = 0, hours = 0, t;
// check if id is passed or the actual element reference
if (typeof element === 'string') {
element = document.getElementById(element);
}
// get reference to component elements inside
hrs = element.querySelector('.hours');
mins = element.querySelector('.minutes');
secs = element.querySelector('.seconds');
start = element.querySelector('.start');
stop = element.querySelector('.stop');
clear = element.querySelector('.clear');
function runWatch() {
seconds++;
if (seconds >= 60) {
seconds = 0; minutes++;
if (minutes >= 60) {
minutes = 0; hours++;
}
}
/* Hours */
if (hours == null) {
hrs.textContent = "00";
} else {
hrs.textContent = hours > 9 ? hours : "0" + hours;
}
/* Minutes */
if (minutes == null) {
mins.textContent = "00";
} else {
mins.textContent = minutes > 9 ? minutes : "0" + minutes;
}
/* Seconds */
if (seconds == null) {
secs.textContent = "00";
} else {
secs.textContent = seconds > 9 ? seconds : "0" + seconds;
}
t = setTimeout(runWatch, 1000);
} // End of runWatch
runWatch();
/* Start button */
start.onclick = runWatch;
/* Stop button */
stop.onclick = function() { clearTimeout(t); }
/* Clear button */
clear.onclick = function() {
hrs.textContentL = "00"; mins.textContent = "00"; secs.textContent = "00";
clearTimeout(t);
seconds = 0; minutes = 0; hours = 0;
}
}
* { box-sizing: border-box; margin: 0; padding: 0; }
div.stopwatch {
width: 180px; border: 1px solid #999;
margin: 8px; display: inline-block;
}
div.stopwatch > div { display: flex; margin: 8px; }
div.stopwatch > div > * { flex: 1 1 auto; }
div.stopwatch > div > span {
text-align: center;
font-family: sans-serif; font-size: 1.7em;
}
div.stopwatch > div > button {
padding: 2px 4px;
}
<div id="sw1" class="stopwatch">
<div>
<span class="hours">00</span>
<span class="minutes">00</span>
<span class="seconds">00</span>
</div>
<div>
<button class="start">start</button>
<button class="stop">stop</button>
<button class="clear">clear</button>
</div>
</div>
<div id="sw2" class="stopwatch">
<div>
<span class="hours">00</span>
<span class="minutes">00</span>
<span class="seconds">00</span>
</div>
<div>
<button class="start">start</button>
<button class="stop">stop</button>
<button class="clear">clear</button>
</div>
</div>