[英]What can I do so functions don't stack?
So this a countdown timer and when I press a button the countdown start by this line: timePassed = timePassed += 1;所以这是一个倒数计时器,当我按下按钮时,倒计时从这条线开始: timePassed = timePassed += 1;
Now the problem is if I press another button to reset the timer the fuctions start stacking on each other and the seconds becomes faster.现在的问题是,如果我按下另一个按钮来重置计时器,这些功能就会开始相互堆叠,并且秒数会变得更快。
i need so that all buttons work and resets the timepassed so they don't stacking...我需要让所有按钮都能正常工作并重置经过的时间,这样它们就不会堆积...
const FULL_DASH_ARRAY = 283; const WARNING_THRESHOLD = 10; const ALERT_THRESHOLD = 5; const COLOR_CODES = { info: { color: "green" }, warning: { color: "orange", threshold: WARNING_THRESHOLD }, alert: { color: "red", threshold: ALERT_THRESHOLD } }; var TIME_LIMIT = 0; let timePassed = 0; let timeLeft = TIME_LIMIT; let timerInterval = null; let remainingPathColor = COLOR_CODES.info.color; document.getElementById("app").innerHTML = ` <div class="base-timer"> <svg class="base-timer__svg" viewBox="0 0 100 100" xmlns="http://www.w3.org/2000/svg"> <g class="base-timer__circle"> <circle class="base-timer__path-elapsed" cx="50" cy="50" r="45"></circle> <path id="base-timer-path-remaining" stroke-dasharray="283" class="base-timer__path-remaining ${remainingPathColor}" d=" M 50, 50 m -45, 0 a 45,45 0 1,0 90,0 a 45,45 0 1,0 -90,0 " ></path> </g> </svg> <span id="base-timer-label" class="base-timer__label">${formatTime( timeLeft )}</span> </div> `; function onTimesUp() { clearInterval(timerInterval); } function formatTime(time) { const minutes = Math.floor(time / 60); let seconds = time % 60; if (seconds < 10) { seconds = `0${seconds}`; } return `${minutes}:${seconds}`; } function setRemainingPathColor(timeLeft) { const { alert, warning, info } = COLOR_CODES; if (timeLeft <= alert.threshold) { document.getElementById("base-timer-path-remaining").classList.remove(warning.color); document.getElementById("base-timer-path-remaining").classList.add(alert.color); } else if (timeLeft <= warning.threshold) { document.getElementById("base-timer-path-remaining").classList.remove(info.color); document.getElementById("base-timer-path-remaining").classList.add(warning.color); } } function calculateTimeFraction() { const rawTimeFraction = timeLeft / TIME_LIMIT; return rawTimeFraction - (1 / TIME_LIMIT) * (1 - rawTimeFraction); } function setCircleDasharray() { const circleDasharray = `${( calculateTimeFraction() * FULL_DASH_ARRAY ).toFixed(0)} 283`; document.getElementById("base-timer-path-remaining").setAttribute("stroke-dasharray", circleDasharray); } function timer15(){ TIME_LIMIT = 901; timePassed = 0; timeLeft = TIME_LIMIT; timerInterval = null; remainingPathColor = COLOR_CODES.info.color; timerInterval = setInterval(() => { timePassed = timePassed += 0; timePassed = timePassed += 1; timeLeft = TIME_LIMIT - timePassed; document.getElementById("base-timer-label").innerHTML = formatTime( timeLeft ); setCircleDasharray(); setRemainingPathColor(timeLeft); if (timeLeft === 0) { onTimesUp(); } }, 1000); } function timer30(){ TIME_LIMIT = 1801; timePassed = 0; timeLeft = TIME_LIMIT; timerInterval = null; remainingPathColor = COLOR_CODES.info.color; timerInterval = setInterval(() => { timePassed = timePassed += 0; timePassed = timePassed += 1; timeLeft = TIME_LIMIT - timePassed; document.getElementById("base-timer-label").innerHTML = formatTime( timeLeft ); setCircleDasharray(); setRemainingPathColor(timeLeft); if (timeLeft === 0) { onTimesUp(); } }, 1000); } function timer45(){ TIME_LIMIT = 2701; timePassed = 0; timeLeft = TIME_LIMIT; timerInterval = null; remainingPathColor = COLOR_CODES.info.color; timerInterval = setInterval(() => { timePassed = timePassed += 1; timeLeft = TIME_LIMIT - timePassed; document.getElementById("base-timer-label").innerHTML = formatTime( timeLeft ); setCircleDasharray(); setRemainingPathColor(timeLeft); if (timeLeft === 0) { onTimesUp(); } }, 1000); } function timer60(){ TIME_LIMIT = 3601; timePassed = 0; timeLeft = TIME_LIMIT; timerInterval = null; remainingPathColor = COLOR_CODES.info.color; timerInterval = setInterval(() => { timePassed = timePassed += 1; timeLeft = TIME_LIMIT - timePassed; document.getElementById("base-timer-label").innerHTML = formatTime( timeLeft ); setCircleDasharray(); setRemainingPathColor(timeLeft); if (timeLeft === 0) { onTimesUp(); } }, 1000); }
body { font-family: sans-serif; display: grid; height: 100vh; place-items: center; }.base-timer { position: relative; width: 300px; height: 300px; }.base-timer__svg { transform: scaleX(-1); }.base-timer__circle { fill: none; stroke: none; }.base-timer__path-elapsed { stroke-width: 7px; stroke: grey; }.base-timer__path-remaining { stroke-width: 7px; stroke-linecap: round; transform: rotate(90deg); transform-origin: center; transition: 1s linear all; fill-rule: nonzero; stroke: currentColor; }.base-timer__path-remaining.green { color: rgb(65, 184, 131); }.base-timer__path-remaining.orange { color: orange; }.base-timer__path-remaining.red { color: red; }.base-timer__label { position: absolute; width: 300px; height: 300px; top: 0; display: flex; align-items: center; justify-content: center; font-size: 48px; }
<,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"> <link rel="stylesheet" href="timer.css"> <title>Document</title> </head> <body> <div id="app"></div> <input type="button" onclick="timer15()" value="15 min"> <input type="button" onclick="timer30()" value="30 min"> <input type="button" onclick="timer45()" value="45 min"> <input type="button" onclick="timer60()" value="60 min"> <script src="timer.js"></script> </body> </html>
In each timerfunction you are setting timerInterval = null
.在每个计时器函数中,您设置timerInterval = null
。 This will not stop or clear the previously registered interval rather only remove its reference from the timerInterval
variable.这不会停止或清除先前注册的间隔,而只会从timerInterval
变量中删除它的引用。 So you have to clear interval first before setting the new time interval.所以你必须在设置新的时间间隔之前先清除间隔。
for example in your timer30 timer45 timer60 functions.例如在你的 timer30 timer45 timer60 函数中。 clear the timerInterval first before setInterval在 setInterval 之前先清除 timerInterval
...
clearInterval(timerInterval);
timerInterval = setInterval(() => { ... }, 1000)
You need to clear intervals one by one, not having only one variable to keep a reference for it.您需要一一清除间隔,而不是只有一个变量来为其保留参考。
Added function to clear intervals and resetting them on each button click to make sure they won't overlap.添加了 function 以清除间隔并在每次单击按钮时重置它们以确保它们不会重叠。
const FULL_DASH_ARRAY = 283; const WARNING_THRESHOLD = 10; const ALERT_THRESHOLD = 5; const COLOR_CODES = { info: { color: "green" }, warning: { color: "orange", threshold: WARNING_THRESHOLD }, alert: { color: "red", threshold: ALERT_THRESHOLD } }; var TIME_LIMIT = 0; let timePassed = 0; let timeLeft = TIME_LIMIT; let timerInterval15 = null; let timerInterval30 = null; let timerInterval45 = null; let timerInterval60 = null; let remainingPathColor = COLOR_CODES.info.color; document.getElementById("app").innerHTML = ` <div class="base-timer"> <svg class="base-timer__svg" viewBox="0 0 100 100" xmlns="http://www.w3.org/2000/svg"> <g class="base-timer__circle"> <circle class="base-timer__path-elapsed" cx="50" cy="50" r="45"></circle> <path id="base-timer-path-remaining" stroke-dasharray="283" class="base-timer__path-remaining ${remainingPathColor}" d=" M 50, 50 m -45, 0 a 45,45 0 1,0 90,0 a 45,45 0 1,0 -90,0 " ></path> </g> </svg> <span id="base-timer-label" class="base-timer__label">${formatTime( timeLeft )}</span> </div> `; function clearIntervals(){ clearInterval(timerInterval15); clearInterval(timerInterval30); clearInterval(timerInterval45); clearInterval(timerInterval60); } function onTimesUp() { clearIntervals(); } function formatTime(time) { const minutes = Math.floor(time / 60); let seconds = time % 60; if (seconds < 10) { seconds = `0${seconds}`; } return `${minutes}:${seconds}`; } function setRemainingPathColor(timeLeft) { const { alert, warning, info } = COLOR_CODES; if (timeLeft <= alert.threshold) { document.getElementById("base-timer-path-remaining").classList.remove(warning.color); document.getElementById("base-timer-path-remaining").classList.add(alert.color); } else if (timeLeft <= warning.threshold) { document.getElementById("base-timer-path-remaining").classList.remove(info.color); document.getElementById("base-timer-path-remaining").classList.add(warning.color); } } function calculateTimeFraction() { const rawTimeFraction = timeLeft / TIME_LIMIT; return rawTimeFraction - (1 / TIME_LIMIT) * (1 - rawTimeFraction); } function setCircleDasharray() { const circleDasharray = `${( calculateTimeFraction() * FULL_DASH_ARRAY ).toFixed(0)} 283`; document.getElementById("base-timer-path-remaining").setAttribute("stroke-dasharray", circleDasharray); } function timer15(){ TIME_LIMIT = 901; timePassed = 0; timeLeft = TIME_LIMIT; clearIntervals(); remainingPathColor = COLOR_CODES.info.color; timerInterval15 = setInterval(() => { timePassed = timePassed += 0; timePassed = timePassed += 1; timeLeft = TIME_LIMIT - timePassed; document.getElementById("base-timer-label").innerHTML = formatTime( timeLeft ); setCircleDasharray(); setRemainingPathColor(timeLeft); if (timeLeft === 0) { onTimesUp(); } }, 1000); } function timer30(){ TIME_LIMIT = 1801; timePassed = 0; timeLeft = TIME_LIMIT; clearIntervals(); remainingPathColor = COLOR_CODES.info.color; timerInterval30 = setInterval(() => { timePassed = timePassed += 0; timePassed = timePassed += 1; timeLeft = TIME_LIMIT - timePassed; document.getElementById("base-timer-label").innerHTML = formatTime( timeLeft ); setCircleDasharray(); setRemainingPathColor(timeLeft); if (timeLeft === 0) { onTimesUp(); } }, 1000); } function timer45(){ TIME_LIMIT = 2701; timePassed = 0; timeLeft = TIME_LIMIT; clearIntervals(); remainingPathColor = COLOR_CODES.info.color; timerInterval45 = setInterval(() => { timePassed = timePassed += 1; timeLeft = TIME_LIMIT - timePassed; document.getElementById("base-timer-label").innerHTML = formatTime( timeLeft ); setCircleDasharray(); setRemainingPathColor(timeLeft); if (timeLeft === 0) { onTimesUp(); } }, 1000); } function timer60(){ TIME_LIMIT = 3601; timePassed = 0; timeLeft = TIME_LIMIT; clearIntervals(); remainingPathColor = COLOR_CODES.info.color; timerInterval60 = setInterval(() => { timePassed = timePassed += 1; timeLeft = TIME_LIMIT - timePassed; document.getElementById("base-timer-label").innerHTML = formatTime( timeLeft ); setCircleDasharray(); setRemainingPathColor(timeLeft); if (timeLeft === 0) { onTimesUp(); } }, 1000); }
body { font-family: sans-serif; display: grid; height: 100vh; place-items: center; }.base-timer { position: relative; width: 300px; height: 300px; }.base-timer__svg { transform: scaleX(-1); }.base-timer__circle { fill: none; stroke: none; }.base-timer__path-elapsed { stroke-width: 7px; stroke: grey; }.base-timer__path-remaining { stroke-width: 7px; stroke-linecap: round; transform: rotate(90deg); transform-origin: center; transition: 1s linear all; fill-rule: nonzero; stroke: currentColor; }.base-timer__path-remaining.green { color: rgb(65, 184, 131); }.base-timer__path-remaining.orange { color: orange; }.base-timer__path-remaining.red { color: red; }.base-timer__label { position: absolute; width: 300px; height: 300px; top: 0; display: flex; align-items: center; justify-content: center; font-size: 48px; }
<,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"> <link rel="stylesheet" href="timer.css"> <title>Document</title> </head> <body> <div id="app"></div> <input type="button" onclick="timer15()" value="15 min"> <input type="button" onclick="timer30()" value="30 min"> <input type="button" onclick="timer45()" value="45 min"> <input type="button" onclick="timer60()" value="60 min"> <script src="timer.js"></script> </body> </html>
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.