所以這是一個倒數計時器,當我按下按鈕時,倒計時從這一行開始: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 >
<svg viewBox="0 0 100 100" xmlns="http://www.w3.org/2000/svg">
<g >
<circle cx="50" cy="50" r="45"></circle>
<path
id="base-timer-path-remaining"
stroke-dasharray="283"
hljs-subst">${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" >${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>
uj5u.com熱心網友回復:
您需要一個一個地清除間隔,而不是只有一個變數來保留它的參考。
添加了清除間隔并在每次單擊按鈕時重置間隔的功能,以確保它們不會重疊。
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 >
<svg viewBox="0 0 100 100" xmlns="http://www.w3.org/2000/svg">
<g >
<circle cx="50" cy="50" r="45"></circle>
<path
id="base-timer-path-remaining"
stroke-dasharray="283"
hljs-subst">${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" >${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>
uj5u.com熱心網友回復:
在您設定的每個計時器功能中timerInterval = null。這不會停止或清除先前注冊的間隔,而只會從timerInterval變數中洗掉其參考。所以你必須先清除間隔,然后才能設定新的時間間隔。
例如在您的 timer30 timer45 timer60 函式中。在 setInterval 之前先清除 timerInterval
...
clearInterval(timerInterval);
timerInterval = setInterval(() => { ... }, 1000)
轉載請註明出處,本文鏈接:https://www.uj5u.com/gongcheng/376160.html
標籤:javascript html 功能
上一篇:如何使用重復、while回圈或其他迭代技術撰寫根據某些規則回傳輸入向量索引的函式
下一篇:這個C語言陳述句是什么意思?
