.gif)
const $timerDisplay = document.querySelector('.display__time-left');
const $customForm = document.querySelector('#custom');
const $customTimeInput = document.querySelector('input[name="minutes"]');
const $timerButtons = document.querySelectorAll('.timer__button');
$customForm.addEventListener('submit', handleCustomTimeInput)
$timerButtons.forEach(($timerButton) => {
$timerButton.addEventListener('click',() => displayCountdown(
$timerButton.dataset.time
))
})
function handleCustomTimeInput(e) {
e.preventDefault();
displayCountdown($customTimeInput.value);
}
function displayCountdown(seconds) {
const min = Math.floor(seconds / 60);
const secondsLeft = seconds % 60;
$timerDisplay.textContent = `${min} : ${secondsLeft}`;
}
어떤 다른 방법으로 일정한 타이머를 구현할 수 있을까?
function timer(seconds) {
const now = Date.now();
const then = now + seconds * 1000;
setInterval(() => {
const secondsLeft = Math.round((then - Date.now()) / 1000);
console.log(secondsLeft);
}, 1000);
seconds를 넣으면, 현재 시각에서 넣은 seconds를 더한다.
그 뒤 현재시각을 1초마다 받아와 빼준다.
헷갈린다면 아래 그림을 참고하자.

그냥 1초마다 지정한 시간에서 1초씩 빼면 되는 거 아니야?
굳이 이렇게 번거롭게 하는 이유가 있다.
브라우저가 버벅이거나 맥에서 스크롤하는 등의 특정 상황에서 setInterval함수가 원활히 작동하지 않을 수 있다. 그런 경우에도 계속해서 현재시간을 받아와 빼준다면 금방 정상화되기 때문에, 위와 같이 하는 것이다.
setInterval함수는 가끔 요상하게 움직이기 때문에.....알아두면 좋은 트릭이다.
다른 버튼을 눌렀을 때 setInterval함수가 겹치지 않아야 하기 때문에, 함수가 실행되었더라도 초기화할 수 있도록 가장 처음에 clearInterval을 해준다. 타이머를 선언한 이전에 clearInterval을 해주어야 하기 때문에 미리 let으로 최상단에 선언해준다음 할당해주었다.
맨 처음 자바스크립트로 게임을 만들 때가 떠올랐다...그 때 setInterval을 처음 다루면서 두 개의 함수가 겹치거나 clearInterval을 제대로 못 써서 곤란했었는데, 함수 처음에 clearInterval로 초기화 해주는 건 아주 좋은 방법인 것 같다. 기억하자!
let countdown;
function timer(seconds) {
clearInterval(countdown);
const now = Date.now();
const then = now + seconds * 1000;
countdown = setInterval(() => {
const secondsLeft = Math.round((then - Date.now()) / 1000);
displayCountdown(secondsLeft)
if(secondsLeft <= 0) clearInterval(countdown);
}, 1000)
}

너무 멋이 없다.
한 자리 수 일때는 앞에 0을 붙여주자.

됐다!
function displayEndTime(time) {
const date = new Date(time);
const hour = date.getHours();
const minutes = date.getMinutes();
const seconds = date.getSeconds();
$endTime.textContent = `${hour}시 ${minutes}분 ${seconds}초에 종료됩니다`
}
function timer(seconds) {
clearInterval(countdown);
const now = Date.now();
const then = now + seconds * 1000;
displayEndTime(then);//
countdown = setInterval(() => {
const secondsLeft = Math.round((then - Date.now()) / 1000);
displayCountdown(secondsLeft)
console.log(secondsLeft)
if(secondsLeft <= 0) clearInterval(countdown);
}, 1000)
}
맨 처음 카운트 다운할 시간을 입력받으면, Date.now()값에 카운트 다운할 시간을 더한 then을 만들었었다. 이것이 우리가 이동할 시간이므로, displayEndTime(then)을 해주면 된다.
아래와 같이 setInterval이 시작되어 1초가 지나야만 화면에 남은 시간이 표시되기 떄문에
첫화면에서 시간을 표시해주어야 한다.
.gif)
function timer(seconds) {
clearInterval(countdown);
const now = Date.now();
const then = now + seconds * 1000;
displayCountdown(seconds)//
displayEndTime(then);
countdown = setInterval(() => {
const secondsLeft = Math.round((then - Date.now()) / 1000);
displayCountdown(secondsLeft)
console.log(secondsLeft)
if(secondsLeft <= 0) clearInterval(countdown);
}, 1000)
}