Skip to content

Instantly share code, notes, and snippets.

@joekrump
Last active April 28, 2022 16:27
Show Gist options
  • Save joekrump/096b124d5eac4c99717496c3b34a6c93 to your computer and use it in GitHub Desktop.
Save joekrump/096b124d5eac4c99717496c3b34a6c93 to your computer and use it in GitHub Desktop.
Timer button - Plain JavaScript and HTML
<!DOCTYPE html>
<html>
<head>
<title>Timer</title>
<style>
:root {
--text-color: black;
--background-color: white;
--backdrop-light: 0%;
}
@media (prefers-color-scheme: dark) {
:root {
--text-color: white;
--background-color: black;
--backdrop-light: 100%;
}
}
body {
background-color: var(--background-color);
}
section {
display: grid;
grid-template-columns: repeat(10, 1fr);
gap: 1rem;
align-items: center;
justify-items: center;
}
button {
padding: 12px 8px;
backdrop-filter: blur(40px);
background-color: hsl(0 0% var(--backdrop-light) / 50%);
border: 1px solid var(--text-color);
border-radius: 8px;
cursor: pointer;
color: var(--text-color);
flex-wrap: nowrap;
display: flex;
justify-content: space-between;
}
.timer-button .icon {
margin-right: 4px;
}
.time {
font-variant-numeric: tabular-nums;
}
.timer-button {
font-size: 2ch;
font-weight: 700;
}
</style>
</head>
<body>
<button class="reset-timers-button">Reset Timers</button>
<section>
</section>
<script>
for (let i = 0; i < 800; i++) {
document.body.querySelector("section").innerHTML += `
<button class="timer-button">
<span class="icon play">▶️</span>
<span class="time" data-seconds="0" data-minutes="0" data-hours="0">00:00:00</span>
</button>
`;
}
const timerButtons = document.querySelectorAll("button.timer-button");
const resetTimersButton = document.querySelector(".reset-timers-button");
let isTimerTicking;
let intervalId;
resetTimersButton.addEventListener("click", (_e) => resetTime());
for (const timerButton of timerButtons) {
timerButton.addEventListener("click", () => {
isTimerTicking = timerButtons.item(0).querySelector(".icon").classList.contains("pause");
if (isTimerTicking) {
clearInterval(intervalId);
window.dispatchEvent(new CustomEvent("pause:time"));
} else {
for (const timerButton of timerButtons) {
updateButtonIcon(timerButton.querySelector(".icon"), "⏸");
}
intervalId = dispatchTickEvent(timerButton.querySelector(".time"), 1000);
}
});
}
window.addEventListener("tick:time", ({ detail: time }) => {
const buttons = document.querySelectorAll("button.timer-button");
const firstButton = buttons.item(0);
for (const button of buttons) {
updateButtonTime(button.querySelector(".time"), time);
}
});
window.addEventListener("pause:time", (_e) => {
const buttons = document.querySelectorAll("button.timer-button");
for (const button of buttons) {
updateButtonIcon(button.querySelector(".icon"), "▶️");
}
});
function updateButtonIcon(iconElement, content) {
updateButtonIconClass(iconElement);
updateButtonIconContent(iconElement, content);
}
function dispatchTickEvent(timeElement, intervalMilliSeconds) {
return setInterval(() => {
window.dispatchEvent(new CustomEvent("tick:time", {
detail: getCurrentButtonTime(timeElement)
}));
}, intervalMilliSeconds);
}
function getCurrentButtonTime(buttonTimeElement) {
return {
seconds: parseInt(buttonTimeElement.dataset.seconds, 10),
minutes: parseInt(buttonTimeElement.dataset.minutes, 10),
hours: parseInt(buttonTimeElement.dataset.hours, 10),
};
}
function updateButtonTime(buttonTimeElement, newTime) {
setTime(buttonTimeElement, incrementTime(newTime.seconds, newTime.minutes, newTime.hours))
}
function updateButtonIconClass(iconElement) {
iconElement.classList.toggle("pause");
iconElement.classList.toggle("play");
}
function updateButtonIconContent(iconElement, content) {
iconElement.innerHTML = content;
}
function setTime(timeElement, { seconds, minutes, hours }) {
timeElement.setAttribute("data-seconds", seconds);
timeElement.setAttribute("data-minutes", minutes);
timeElement.setAttribute("data-hours", hours);
timeElement.innerHTML = getFormattedTime({ hours, minutes, seconds });
}
function resetTime() {
const buttonTimeElements = document.querySelectorAll("button.timer-button .time");
for (const timeElement of buttonTimeElements) {
setTime(timeElement, { seconds: 0, minutes: 0, hours: 0 });
}
}
function incrementTime(seconds = 0, minutes = 0, hours = 0) {
if (seconds === 59) {
seconds = 0;
minutes++;
} else {
seconds++;
}
if (minutes === 59) {
minutes = 0;
hours++;
}
return {
seconds,
minutes,
hours
};
}
function getFormattedTime({ hours, minutes, seconds }) {
let formattedSeconds = seconds;
let formattedMinutes = minutes;
let formattedHours = hours;
if (seconds < 10) {
formattedSeconds = `0${seconds}`;
}
if (minutes < 10) {
formattedMinutes = `0${minutes}`;
}
if (hours < 10) {
formattedHours = `0${hours}`;
}
return `${formattedHours}:${formattedMinutes}:${formattedSeconds}`;
}
</script>
</body>
</html>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment