만들고자 하는 것에 대해 주어진 정보는 충분해 보이니, 차근차근 만들 수 있겠습니다.
- 타이머가 중복으로 만들어지는 게 문제
버튼을 클릭하면, 버튼 요소에 등록된 리스너가 타이머를 생성하고, 그 타이머가 HTML 텍스트를 변화시키는 것입니다. 여기서 중요한 것은, 진행되는 타이머는 유일해야 한다는 것입니다. 하지만 기존의 코드는 타이머를 클릭하는 대로 우후죽순 만들고, 표시되는 텍스트는 유일하기 때문에 여러 타이머가 동시에 한 텍스트를 건드니 타이머가 원하는 대로 작동하지 않는 것입니다.
- 타이머를 하나만 생성하도록 관리하는 방법
만드는 데엔 여러 방식이 있겠지만, 막무가내로 일단 가장 간단한 방식으로 만들겠습니다.
염두에 둬야 하는 것은 아래와 같습니다.
- 페이지 내에서 작동하는 타이머는 유일하다.
- 버튼을 클릭했을 때 작동하던 타이머가 있다면 그 타이머를 제거하고 새로운 타이머로 교체한다.
- 타이머가 종료되면 종료된 타이머를 제거한다.
세세한 코드 스타일은 다를 수 있겠지만, 최대한 기존의 코드를 활용하겠습니다.
const INTERVAL = 1000;
const START_COUNTDOWN = 30;
const startButton = document.querySelector(".start_btn");
const timerText = document.querySelector(".time_text");
let currentTimer = null; // 실행되는 타이머가 할당될 변수
let currentCountdown = START_COUNTDOWN; // 타이머가 표시할 카운트다운
currentTimer
에 실행되는 타이머가 없으면 null
상태로 만들고, 반대로 currentTimer
가 null
이 아니라면 진행되는 타이머가 존재한다는 의미로 활용합니다.
이 흐름에 맞춰서 이벤트 리스너도 조정합니다.
startButton.addEventListener("click", () => {
if (currentTimer === null) {
// 타이머가 존재하지 않는 경우
} else {
// 기존에 작동하는 타이머가 존재하는 경우
}
});
이벤트 리스너 내부의 콜백 함수는 다음처럼 정리할 수 있습니다.
- 작동하는 타이머가 존재하지 않는다면
- 새로운 타이머를 만들어
currentTimer
에 할당한다.
- 이미 작동하는 타이머가 존재한다면
- 기존의 타이머를 제거한다.
- 새로운 타이머를 만들어
currentTimer
에 할당한다.
새로운 타이머를 만드는 기능이 중복되므로 함수로 따로 생성하겠습니다.
function createTimer() {
// setInterval은 바로 시작하지 않기 때문에 클릭 직후의 상황을 미리 설정해 둠
currentCountdown = START_COUNTDOWN;
timerText.innerHTML = `${currentCountdown}`;
currentTimer = setInterval(() => {
currentCountdown -= 1;
timerText.innerHTML = `${currentCoundown}`;
if (currentCountdown === 0) {
clearInterval(currentTimer);
currentTimer = null;
console.log("종료");
}
}, INTERVAL);
}
콜백 함수는 아래처럼 채워집니다.
startButton.addEventListener("click", () => {
if (currentTimer === null) {
createTimer();
} else {
// 기존에 작동하는 타이머가 존재하는 경우
}
});
테스트 결과, 타이머가 정상적으로 종료되는 것을 확인했습니다.
이제 남은 부분을 채우면 됩니다.
startButton.addEventListener("click", () => {
if (currentTimer === null) {
createTimer();
} else {
clearInterval(currentTimer);
console.log("타이머 제거됨");
createTimer();
}
});
기존에 작동되는 타이머가 있으면 취소가 되고 새로 타이머가 생성돼 할당되는 것을 확인할 수 있었습니다.
전체 코드는 여기에서 확인하실 수 있습니다.
https://codesandbox.io/s/timer00-pud8ql?file=/index.html