JavaScript 타이머 산수 · Enter 계산기
이 폴더의 예제는 이전 산수 게임을 이벤트와 타이머로 확장합니다. 사용자가 직접 버튼을 누르는 흐름뿐 아니라 시간이 지나면 자동으로 채점되는 흐름, 키보드 입력 이벤트, 마우스 이동과 이미지 변경 이벤트를 함께 다룹니다.
타이머 산수 게임은 문제 생성, 카운트다운, 자동 채점 세 단계로 움직입니다. body onload에서 makeExpression()과 startTimer()를 연달아 실행합니다.
| 함수 | 역할 | 핵심 상태 |
|---|---|---|
| makeExpression | 문제와 입력칸 초기화 | question, answer |
| startTimer | 점수와 카운트다운 초기화 | countDown, timerID |
| timeout | 1초마다 남은 시간 감소 | clock |
| calc | 정답 비교와 점수 출력 | score |
원본은 10초 동안이라는 주석과 함께 countDown = 11로 초기화합니다. timeout 함수가 시작하자마자 먼저 1을 빼기 때문에 화면에는 10부터 보입니다.
| 순서 | countDown | 화면 표시 |
|---|---|---|
| 초기화 | 11 | 아직 표시 전 |
| 첫 timeout | 10 | 10 |
| 1초 후 | 9 | 9 |
| 마지막 | 0 | 채점 실행 |
다시 버튼을 누를 때 기존 타이머가 남아 있으면 카운트다운이 여러 개 동시에 실행될 수 있습니다. 그래서 새 타이머를 시작하기 전에 기존 timerID를 정리합니다.
countDown == 0이 되면 더 이상 timeout을 예약하지 않고 calc()를 호출합니다. 이 순간 사용자가 입력한 답을 기준으로 점수가 결정됩니다.
채점 로직은 79번 산수 게임과 거의 같습니다. question class의 식을 계산하고 answer class의 입력값과 비교합니다.
| 조건 | 판정 | 처리 |
|---|---|---|
| 빈 답 | 오답 | 문제에 줄긋기 |
| 문자 | 오답 | isNaN으로 걸러냄 |
| 정답 | 점수 증가 | 줄긋기 제거 |
| 오답 | 점수 변화 없음 | 문제에 줄긋기 |
계산기 예제는 입력창에서 키를 누를 때마다 onkeydown이 실행되고, 눌린 키가 Enter이면 수식을 계산합니다.
| 코드 | 의미 | 예시 |
|---|---|---|
| onkeydown | 키를 누르는 순간 발생 | Enter 입력 |
| event | 키 이벤트 정보 | e.key |
| e.key == "Enter" | Enter 키 판정 | 계산 실행 조건 |
| result.value | 결과 input에 값 넣기 | 계산 결과 표시 |
두 예제 모두 eval을 사용합니다. 산수 게임은 코드가 만든 식을 계산하지만, 계산기 예제는 사용자가 직접 입력한 문자열을 실행하므로 더 위험합니다.
| 상황 | 위험도 | 대안 |
|---|---|---|
| 코드가 만든 단순 산수식 | 상대적으로 낮음 | 허용 문자 제한 |
| 사용자 직접 입력 | 높음 | 수식 파서 또는 검증 |
| 문자열 코드 실행 | 높음 | 함수 참조 사용 |
| 학습용 로컬 예제 | 허용 가능 | 위험성 함께 이해 |
| 실수 | 증상 | 해결 |
|---|---|---|
| timerID 정리 누락 | 타이머가 중복 실행됩니다. | 새 시작 전에 clearTimeout을 호출합니다. |
| countDown 초기값 혼동 | 10초가 아닌 것처럼 보입니다. | 처음에 1 감소한다는 흐름을 봅니다. |
| Enter 키 비교 오타 | 계산이 실행되지 않습니다. | e.key 값이 "Enter"인지 확인합니다. |
| eval 오류 처리 없음 | 잘못된 수식에서 콘솔 오류가 납니다. | try/catch나 입력 검증을 추가합니다. |
| score 초기화 누락 | 다시 시작해도 이전 점수가 남습니다. | startTimer에서 0으로 초기화합니다. |
| 체크 | 통과 기준 |
|---|---|
| setTimeout | 한 번 예약 후 다시 예약하는 반복 구조를 설명합니다. |
| clearTimeout | 중복 타이머 방지 목적을 압니다. |
| countDown | 11에서 시작해 10부터 표시되는 이유를 압니다. |
| calc | 자동 채점과 수동 채점 로직을 이해합니다. |
| onkeydown | Enter 키 판정 흐름을 설명합니다. |
| eval | 편리함과 위험성을 함께 설명합니다. |
| 확인 | 콘솔 예시 | 의미 |
|---|---|---|
| 타이머 ID | console.log(timerID) | 예약이 저장되는지 확인합니다. |
| 남은 시간 | console.log(countDown) | 1초마다 줄어드는지 봅니다. |
| 키 값 | console.log(e.key) | Enter 값이 정확한지 확인합니다. |
| 수식 값 | console.log(exp.value) | 계산할 문자열을 확인합니다. |
| 점수 | console.log(total) | 정답 수가 누적되는지 봅니다. |
| 케이스 | 준비 | 예상 결과 |
|---|---|---|
| 로드 직후 | 페이지 열기 | 문제 생성과 10초 표시 |
| 시간 종료 | 10초 대기 | 자동 채점 실행 |
| 다시 버튼 | 중간에 클릭 | 새 문제와 새 타이머 시작 |
| Enter 계산 | 1+2 입력 후 Enter | 결과 3 출력 |
| 잘못된 식 | 1+ 입력 후 Enter | eval 오류 가능 |
타이머 산수 게임은 작은 기능을 붙이기 좋은 예제입니다. 시간 제한, 채점, 키보드 이벤트가 이미 있으므로 상태 관리 연습에 적합합니다.
| 개선 | 이유 | 확인 포인트 |
|---|---|---|
| 남은 시간 색상 | 긴박감을 보여줍니다. | 3초 이하에서 빨간색 표시 |
| 정답 표시 | 학습 효과를 높입니다. | 채점 후 correctAnswer 출력 |
| 점수 문장화 | 결과를 읽기 쉽게 만듭니다. | 4문제 중 3문제 정답 |
| 새 문제 잠금 | 채점 중 상태 꼬임을 줄입니다. | 타이머 정리 후 재시작 |
| 수식 검증 | eval 오류를 줄입니다. | 숫자와 연산자만 허용 |
이 예제에서 가장 중요한 상태는 timerID, countDown, score입니다. 각각의 역할을 분리해서 보면 버그를 줄일 수 있습니다.
| 상태 | 저장 위치 | 변경 시점 |
|---|---|---|
| timerID | 전역 변수 | setTimeout 등록, clearTimeout 정리 |
| countDown | 전역 변수 | startTimer 초기화, timeout 감소 |
| score | span innerHTML | startTimer 초기화, calc 결과 출력 |
| question | td innerHTML | makeExpression에서 새 식으로 교체 |
| answer | input value | 사용자 입력, 다시 버튼에서 초기화 |
| result | input value | Enter 계산기에서 계산 결과 저장 |
| exp | input value | 사용자가 입력한 수식 문자열 |
핵심 한 줄 요약
Tags
'php' 카테고리의 다른 글
| JavaScript e.target 이벤트 완전 정리 (0) | 2026.07.06 |
|---|---|
| JavaScript 계산기 · DOM 실습 완전 정리 (0) | 2026.07.06 |
| JavaScript onmousemove · onblur · radio 이미지 완전 정리 (0) | 2026.07.06 |
| JavaScript 산수 게임 완전 정리 (0) | 2026.07.06 |
| JavaScript 디지털시계 — setInterval·setTimeout 완전 정리 (0) | 2026.07.06 |
왕진 블로그

댓글