繁体   English   中英

我该怎么做才能使函数不堆叠?

[英]What can I do so functions don't stack?

所以这是一个倒数计时器,当我按下按钮时,倒计时从这条线开始: timePassed = timePassed += 1;

现在的问题是,如果我按下另一个按钮来重置计时器,这些功能就会开始相互堆叠,并且秒数会变得更快。

我需要让所有按钮都能正常工作并重置经过的时间,这样它们就不会堆积...

 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>

在每个计时器函数中,您设置timerInterval = null 这不会停止或清除先前注册的间隔,而只会从timerInterval变量中删除它的引用。 所以你必须在设置新的时间间隔之前先清除间隔。

例如在你的 timer30 timer45 timer60 函数中。 在 setInterval 之前先清除 timerInterval

...
clearInterval(timerInterval);

timerInterval = setInterval(() => { ... }, 1000)

您需要一一清除间隔,而不是只有一个变量来为其保留参考。

添加了 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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM