자바스크립트로 타이머 시작 및 정지 버튼 만들기
이제 버튼 두 개를 만들어 보겠습니다. 첫 번째 버튼을 클릭하면 타이머가 시작되고, 두 번째 버튼을 클릭하면 정지되도록 해봅시다. 여기서는 간단하지 않으며 함정이 기다리고 있습니다. 이 함정의 본질을 이해하기 위해 코드 생성 과정을 단계별로 설명하겠습니다.
그럼 두 개의 작은 버튼을 만들어 봅시다:
<button id="start">start</button>
<button id="stop">stop</button>
이 버튼들에 대한 참조를 변수에 저장합니다:
let start = document.querySelector('#start');
let stop = document.querySelector('#stop');
첫 번째 버튼 클릭 시 타이머를 시작하고, 그 ID를 변수에 저장합니다:
start.addEventListener('click', function() {
let timerId = setInterval(function() {
console.log('!')
}, 1000);
});
이제 두 번째 버튼을 클릭하면 타이머를 정지시킵니다:
start.addEventListener('click', function() {
let timerId = setInterval(function() {
console.log('!')
}, 1000);
});
// 타이머 정지:
stop.addEventListener('click', function() {
clearInterval(timerId);
});
그러나 위의 코드를 실행하려고 하면 놀라운 일이 발생합니다: 타이머를 정지하려고 할 때 변수 timerId 가 undefined 인 것으로 판명될 것입니다! 왜 이런 일이 발생했을까요? 타이머를 시작할 때 우리는 start 버튼에 바인딩된 함수 내부에서 timerId 변수를 지역 변수로 만들었기 때문입니다.
이 문제를 해결하기 위해 timerId 변수를 전역 변수로 만들어 봅시다. 이렇게 하면 타이머 시작 함수와 정지 함수 모두에서 접근할 수 있습니다:
let timerId; // 변수를 전역으로 만듭니다
start.addEventListener('click', function() {
timerId = setInterval(function() {
console.log('!')
}, 1000);
});
stop.addEventListener('click', function() {
clearInterval(timerId);
});
초기에 숫자 100 이 저장된 변수가 주어졌다고 가정합니다. 또한 두 개의 버튼이 있습니다. 첫 번째 버튼을 클릭하면 변수 값을 매초 1 씩 감소시키고 새로운 값을 콘솔에 출력하는 타이머를 시작하세요. 변수 값이 0에 도달하면 타이머를 정지하세요.
두 번째 버튼을 클릭하면 타이머를 정지하세요. 또한 두 번째 버튼이 눌리지 않았지만 변수 값이 0에 도달한 경우에도 타이머를 정지하세요.
어떤 프로그래머가 버튼을 클릭하면 현재 시간을 콘솔에 출력하는 타이머를 시작하는 코드를 작성했습니다:
<input type="submit" id="start" value="start">
<input type="submit" id="stop" value="stop">
let start = document.querySelector('#start');
let stop = document.querySelector('#stop');
start.addEventListener('click', function() {
let timerId = setInterval(function() {
let date = new Date;
console.log(date.getMinutes() + ' ' + date.getSeconds());
}, 1000);
});
stop.addEventListener('click', function() {
clearInterval(timerId);
});
그러나 코드를 실행한 후 정지 버튼이 작동하지 않는 것으로 나타났습니다. 코드 작성자의 실수를 수정하세요.
또 다른 프로그래머가 이전 문제를 해결하기 위해 코드를 작성했습니다:
<input type="submit" id="start" value="start">
<input type="submit" id="stop" value="stop">
let start = document.querySelector('#start');
let stop = document.querySelector('#stop');
let timerId;
start.addEventListener('click', function() {
let timerId = setInterval(function() {
let date = new Date;
console.log(date.getMinutes() + ' ' + date.getSeconds());
}, 1000);
});
stop.addEventListener('click', function() {
clearInterval(timerId);
});
그러나 코드를 실행한 후 다시 한번 정지 버튼이 작동하지 않는 것으로 나타났습니다. 코드 작성자의 실수를 수정하세요.
또 다른 프로그래머가 이전 문제를 해결하기 위해 코드를 작성했습니다:
<input type="submit" id="start" value="start">
<input type="submit" id="stop" value="stop">
let start = document.querySelector('start');
let stop = document.querySelector('stop');
let timerId;
start.addEventListener('click', function() {
setInterval(function() {
let date = new Date;
console.log(date.getMinutes() + ' ' + date.getSeconds());
}, 1000);
});
stop.addEventListener('click', function() {
clearInterval(timerId);
});
그러나 코드를 실행한 후 다시 한번 정지 버튼이 작동하지 않는 것으로 나타났습니다. 코드 작성자의 실수를 수정하세요.
또 다른 프로그래머가 이전 문제를 해결하기 위해 코드를 작성했습니다:
<input type="submit" id="start" value="start">
<input type="submit" id="stop" value="stop">
let start = document.querySelector('start');
let stop = document.querySelector('stop');
let timerId;
start.addEventListener('click', function() {
let timerId = setInterval(function() {
let date = new Date;
console.log(date.getMinutes() + ' ' + date.getSeconds());
}, 1000);
});
stop.addEventListener('click', function() {
clearInterval();
});
그러나 코드를 실행한 후 다시 한번 정지 버튼이 작동하지 않는 것으로 나타났습니다. 코드 작성자의 실수를 수정하세요.
이론 부분에서 제시한 코드는 시작 버튼을 여러 번 클릭할 수 있다는 점을 고려하지 않습니다. 이 문제를 해결하기 위해 시작 버튼을 클릭할 때 해당 버튼에서 이벤트를 해제하고, 정지 버튼을 클릭할 때 다시 바인딩할 수 있습니다. 이 문제를 해결하세요.