I am new to web development. What I am trying to do is run more than one Pomodoro timer built with JavaScript in parallel. The problem is when I click on the second start button the first timer stops working.
The goal is each timer should work separately and should show different times when I press the start button.
Sorry for bad css style it is not responsive!
Can anyone help me to find the solution?
const p_Tag = document.querySelectorAll('.text');
p_Tag.forEach(a => {
if (a.textContent === "Next Correction") {
a.parentNode.classList.add("isTimer")
}
})
const getTimerContainer = document.querySelectorAll(".item");
let hasclass = false;
getTimerContainer.forEach(check => {
if (check.classList.contains('isTimer')) {
hasclass = true;
const timerContainer = document.createElement("div");
timerContainer.classList.add("timer");
check.append(timerContainer)
}
});
if (hasclass === true) {
let id = 0;
const timer = document.querySelectorAll(".timer");
let settedTime = '02:⏰';
const place = "beforeend";
timer.forEach(t => {
const timerElm = `
<figure class="clock">
<div class="numberContainer">
<p class="mins" id="hr${id}">00</p>
<p>:</p>
<p class="secs" id="min${id}">00</p>
<br>
<p class="settedTime">${settedTime}</p>
</div>
<audio
src="bell.mp3"
></audio>
<svg class="progress-ring" height="200" width="200">
<circle
class="progress-ring__circle2"
stroke-width="10"
fill="transparent"
r="80"
cx="100"
cy="100"
/>
<circle
class="progress-ring__circle"
stroke-width="15"
fill="transparent"
r="80"
cx="100"
cy="100"
id="${id}"
/>
</svg>
</figure>
<div class="btn-group">
<button class="start" id="s${id}">Start</button>
<button class="reset" id="r${id}">Reset</button>
<button class="halt" id="h${id}">Pause</button>
</div>
</div>
`;
t.insertAdjacentHTML(place, timerElm);
id++
})
};
const bell = document.querySelectorAll("audio");
const minutes = document.querySelectorAll(".mins");
const secondes = document.querySelectorAll(".secs");
const startBtn = document.querySelectorAll(".start");
const pauseBtn = document.querySelectorAll(".halt");
const clockframe = document.querySelectorAll(".progress-ring__circle2");
let initial, totalsecs, perc, paused, mins, seconds;
const circleUp = document.querySelectorAll(".progress-ring__circle")
const circle = document.querySelector(".progress-ring__circle");
const radius = circle.r.baseVal.value;
const circumference = radius * 2 * Math.PI;
let idOfSec = null;
let idOfStartBtn=0;
function setId(t){
t.forEach(tId=>{tId.addEventListener("click",(e)=>{
const item= e.target;
const isId = parseInt(item.id.split("").pop())
idOfStartBtn = isId
})
})
}
const dasharray = circle.style.strokeDasharray = circumference;
const dashoffset= circle.style.strokeDashoffset = circumference;
//console.log("this is the dasharray: ", dasharray);
//console.log("this is the dashoffset: ", dashoffset);
function setProgress(percent) {
const offset = circumference - (percent / 100) * circumference;
//console.log("this is the offset ", offset)
//circleUp.forEach(offset1 => offset1.style.strokeDashoffset= offset)
circle.style.strokeDashoffset = offset ;
}
document.getElementById("s" + idOfStartBtn).addEventListener("click", () => {
setId(startBtn)
mins = 1;
seconds = mins * 60;
totalsecs = mins * 60;
setTimeout(decremenT(idOfStartBtn), 60);
//startBtn.style.transform = "scale(1)";
paused = false;
})
document.getElementById("r" + idOfStartBtn).addEventListener("click", () => {
//startBtn.style.transform = "scale(1)";
clearTimeout(initial);
setProgress(0);
document.getElementById("hr"+idOfStartBtn).textContent = '00';
document.getElementById("min"+idOfStartBtn).textContent = '00';
});
document.getElementById("h" + idOfStartBtn).addEventListener("click", () => {
if (paused === undefined) {
return;
}
if (paused) {
paused = false;
initial = setTimeout(`decremenT(${idOfStartBtn})`, 60);
pause.textContent = "Pause";
pause.classList.remove("Resume");
} else {
clearTimeout(initial);
pause.textContent = "Resume";
pause.classList.add("resume");
paused = true;
}
})
function decremenT(takeId) {
//console.log("this is variable from decremenT:",takeId)
let sec = document.getElementById(`hr${takeId}`).textContent = Math.floor(seconds / 60).toString().padStart(2, "0");
document.getElementById(`min${takeId}`).textContent = seconds % 60 > 9 ? seconds % 60 : `0${seconds % 60}`;
if (circle.classList.contains("danger")) {
circle.classList.remove("danger");
//minutes.classList.remove("beep");
//secondes.classList.remove("beep");
}
if (seconds > 0) {
perc = Math.ceil(((totalsecs - seconds) / totalsecs) * 100);
setProgress(perc);
seconds--;
initial = window.setTimeout(`decremenT(${idOfStartBtn})`, 1000);
if (seconds < 45) {
circle.classList.add("danger");
//minutes.classList.add("beep");
//secondes.classList.add("beep");
}
} else {
mins = 0;
seconds = 0;
bell.play();
}
}
*{
margin:0;
padding:0;
}
body {
background-color: #D9AFD9;
background-image: linear-gradient(0deg, #D9AFD9 0%, #97D9E1 100%);
font-family: 'Microsoft PhagsPa';
height: 100vh;
color: hsl(210, 10%, 10%);
text-shadow: 0 1px 1px hsl(0deg 0% 100% / 50%);
}
.item {
border-radius: 15px;
filter: brightness(95%);
background-size: 450px;
margin: 40px;
box-shadow: 4px 4px 13px rgba(0,0,0,0.3), inset 10px 9px 18px rgba(0,0,0,0.55);
background-color: rgba(255, 255, 255, .15);
backdrop-filter: blur(5px);
}
.item:hover {
color: rgb(77, 74, 137);
opacity: 1;
cursor: pointer;
font-size: 2rem;
box-shadow: 6px 6px 15px rgba(0,0,0,0.3), inset 12px 11px 20px rgba(0,0,0,0.55);
}
#sortable li {
position:relative;
margin: 30px 30px 30px 0px;
padding: 1px;
width: 450px;
height: 458px;
font-size: 2em;
text-align: center;
}
#sortable {
display: flex;
flex-wrap: wrap;
list-style: none;
justify-content: center;
min-height: 200px;
padding-bottom:100px;
}
.clock {
padding: 3px;
display: flex;
justify-content: center;
align-items: center;
font-weight: bold;
height: 18vh;
width:18vh;
font-size: 24px;
}
.progress-ring {
position: absolute;
top: 10vh;
left: 5vw;
transform: translate(-50%, -50%);
}
.progress-ring__circle {
transition: 0.5s;
transform: rotate(-90deg);
transform-origin: 50% 50%;
stroke: rgba(142, 68, 173,1);
}
.progress-ring__circle2 {
transition: 0.5s;
transform: rotate(-90deg);
transform-origin: 50% 50%;
stroke: rgb(189, 195, 199);
}
.btn-group {
display: flex;
justify-content: start;
align-items: start;
height: 10%;
position: relative;
top: 10vh;
right: 50px;
z-index:1;
}
.timer {
height: 212px;
width: 212PX;
position: relative;
top: 200px;
left:200px;
}
.start {
background: rgb(48, 33, 253);
color: white;
margin-right: 5px;
padding: 2px;
width: 60px;
}
.break {
background: rgb(0, 199, 116);
color: #000000;
margin-right:5px;
padding:2px;
}
.reset {
background: rgb(250, 69, 109);
color: #000000;
margin-right: 5px;
padding: 2px;
width: 60px;
}
.halt {
background: rgb(253, 143, 17);
padding: 2px;
width: 60px
}
.resume {
background: rgb(131, 10, 252);
color: white;
width: 60px;
}
.danger {
stroke: rgba(243, 17, 28, 1);
animation: pulse 0.9s ease-in-out infinite;
}
.beep {
color: rgba(192, 57, 43,1.0);
animation: beep 0.9s infinite;
border-radius:50%;
}
.settedTime {
position: absolute;
top: 70px;
font-size: 14px;
align-items: center;
text-align: center;
padding-top: 0px;
opacity:.5;
}
.numberContainer {
display: inline-flex;
justify-content: center;
}
@keyframes pulse {
0%,100% {
transform: rotate(-90deg) scale(1);
}
50% {
transform: rotate(-90deg) scale(1.04);
box-shadow: 0 0 0 3px rgba(243, 17, 28, 0.8);
}
75% {
transform: rotate(-90deg) scale(1.01);
}
}
@keyframes beep {
0% {
transform: scale(0.9);
box-shadow: 0 0 0 0 rgba(192, 57, 43,0.2);
}
70% {
transform: scale(1);
box-shadow: 0 0 0 20px rgba(192, 57, 43,0);
}
100% {
transform: scale(0.9);
}
}
.text {
position: absolute;
top: 412px;
text-align: center;
/*border-top: solid;*/
-webkit-user-select: none;
left: 0px;
width: 100%;
}
<!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>Timer</title>
</head>
<body>
<ul id="sortable" class="row itemContainer">
<li class="item col-xs-4 col-sm-2 col-md-1">
<p class="text">Next Correction</p>
<div class="inner"><div class="resize"></div></div>
</li>
<li class="item col-xs-4 col-sm-2 col-md-1 ">
<p class="text">Next Correction</p>
<div class="inner"><div class="resize"></div></div>
</li>
<li class="item col-xs-4 col-sm-2 col-md-1 " >
<p class="text">Next Correction</p>
<div class="inner"><div class="resize"></div></div>
</li>
</ul>
</body>
</html>