자바스크립트 OX 퀴즈 만들기: 5초 제한 시간 기능 포함

웹 개발 공부를 시작하면서 가장 먼저 마주하는 난관 중 하나가 “내가 배운 문법을 어떻게 실제 기능으로 구현할 것인가?”입니다. 변수, 함수, 조건문은 익혔지만 이를 조합해 하나의 ‘서비스’를 만드는 경험은 또 다른 영역이죠.

오늘 함께 만들어볼 ‘자바스크립트 OX 퀴즈‘는 자바스크립트의 핵심 개념들을 골고루 실습해볼 수 있는 아주 좋은 프로젝트입니다. 화면에 문제를 띄우는 DOM 조작부터, 정답 여부를 판별하는 조건문, 그리고 사용자의 긴장감을 유발하는 타이머(Timer API) 기능까지 한 번에 학습할 수 있습니다.

특히 이번 프로젝트에서는 단순히 정답만 맞히는 것이 아니라, 5초라는 제한 시간을 두어 시각적으로 시간이 줄어드는 ‘타이머 바’ 애니메이션까지 추가하여 구현해 보겠습니다.


자바스크립트 OX 퀴즈 만들기 메인 화면

1. 설계

코드를 작성하기 전, 우리가 만들 프로그램의 로직을 머릿속으로 그려보는 과정이 필요합니다.

  • 데이터 관리: 퀴즈 문제와 정답 정보를 담고 있는 객체 배열이 필요합니다.
  • 화면 구성: 퀴즈가 진행되는 화면과 결과가 출력되는 화면을 각각 설계하고 상황에 따라 전환해줍니다.
  • 시간 제한: 문제마다 일정 시간을 부여하고, 시간이 흐를수록 줄어드는 게이지를 시각적으로 보여줍니다.
  • 점수 계산: 사용자가 클릭한 답과 실제 정답을 비교해 점수를 누적합니다.

2. 자바스크립트 OX 퀴즈 HTML & CSS

전체적인 외형은 심플하고 깔끔하게 구성하였습니다.
웹 서비스에서 사용자 경험(UX)은 매우 중요합니다.
모바일에서도 편하게 퀴즈를 풀 수 있도록 반응형 레이아웃을 구성했습니다.
CSS 변수(:root)를 사용하여 주요 색상을 관리하도록 하였습니다.

<div class="quiz-container">
    <div class="timer-wrapper">
        <div id="timer-bar"></div>
    </div>

    <div id="quiz-screen">
        <div class="quiz-header">
            <h2 id="question-number">Question 1</h2>
        </div>
        <div id="question-text">준비중...</div>
        <div class="options">
            <button class="btn btn-o" onclick="handleAnswer(true)">O</button>
            <button class="btn btn-x" onclick="handleAnswer(false)">X</button>
        </div>
    </div>

    <div id="result-screen" class="hidden">
        <div class="result-icon">🏆</div>
        <h3>퀴즈 종료!</h3>
        <p id="score-text"></p>
        <button class="btn btn-retry" onclick="resetQuiz()">다시 시작하기</button>
    </div>
</div>

3. 자바스크립트 OX 퀴즈 코드 분석

이제 가장 중요한 자바스크립트 로직을 살펴보겠습니다. 이 코드의 핵심은 “시간을 어떻게 정밀하게 계산하는가”“화면을 어떻게 갱신하는가”에 있습니다.

① 정밀한 타이머 구현 (Date.now() 활용)

일반적으로 setInterval을 사용해 시간을 깎아내려가지만, 자바스크립트의 이벤트 루프 특성상 미세한 오차가 발생할 수 있습니다. 그래서 이번 코드에서는 Date.now()를 활용해 시작 시점과 현재 시점의 차이(elapsedTime)를 계산했습니다. 이렇게 하면 브라우저의 성능 상황과 관계없이 항상 정확하게 5초 뒤에 타이머가 종료됩니다.

const elapsedTime = Date.now() - startTime;
const remaining = Math.max(0, 100 - (elapsedTime / TIME_LIMIT) * 100);
  • 대부분 타이머를 만들 때 단순히 setInterval만 사용하여 시간을 1초씩 깎는 방식을 선택하곤 합니다. 하지만 자바스크립트의 엔진은 싱글 스레드로 동작하기 때문에, 다른 복잡한 연산이 실행 중일 경우 setInterval의 호출이 지연될 수 있습니다. 이번 프로젝트에서 제가 Date.now()를 활용해 실제 경과 시간을 계산한 이유가 바로 여기에 있습니다. 시작 시간과 현재 시간을 비교하는 방식은 브라우저에 부하가 걸리더라도 정확한 ‘절대 시간’을 반영하므로, 사용자에게 훨씬 더 정밀하고 끊김 없는 타이머 경험을 제공할 수 있습니다.

② 사용자 피드백: 시각적 긴박감 조성

시간이 70% 이상 남았을 때는 안정감을 주는 오렌지색을 유지하다가, 30% 미만으로 떨어지는 순간 강렬한 빨간색으로 변하게 설정했습니다. 이러한 시각적 피드백은 텍스트로 ‘시간이 얼마 남지 않았습니다’라고 알려주는 것보다 훨씬 강력하게 사용자의 긴장감을 유발하고 게임에 몰입하게 만듭니다.

③ 결과 화면 전환 (Hidden 클래스)

워드프레스나 최신 웹 프레임워크에서 자주 쓰이는 방식인 ‘클래스 제어’를 통해 화면을 전환합니다. hidden이라는 클래스를 추가하거나 제거함으로써 HTML 구조를 바꾸지 않고도 매끄럽게 결과 화면으로 이동할 수 있습니다.

④ 퀴즈 데이터 구조

문제 데이터는 객체 배열로 관리합니다. 문제와 정답의 의미가 분리되어 가독성이 좋고, 추후 문제를 서버나 JSON 파일에서 불러오기 쉽습니다.

const quizData = [
 { question: "자바스크립트는 브라우저에서만 동작한다.", answer: false },
 { question: "JSON.stringify는 객체를 문자열로 변환한다.", answer: true }
];

4. 확장 아이디어

  • 문제 랜덤 섞기: 퀴즈 데이터의 순서를 섞어주는 sort() 로직을 추가하면 사용자가 게임을 재시작할 때마다 새로운 느낌을 줄 수 있습니다.
  • 난이도 조절: 문제 번호가 올라갈수록 TIME_LIMIT 값을 줄여서 난이도를 높이는 코드를 구현해볼 수도 있습니다.
  • 로컬 스토리지 활용: 사용자의 최고 점수를 브라우저에 저장해두고, 다음 방문 때 보여준다면 훨씬 ‘프로그램’다운 면모를 갖추게 됩니다.
  • 서버 연동: 지금은 문제 데이터를 코드 내부에 하드코딩하여 추가해주었지만, 서버에서 관리하면 더욱 완벽한 퀴즈 페이지를 만들 수 있습니다.

5. 자바스크립트 OX 퀴즈 실행 영상

6. 참고


오늘 만든 OX 퀴즈는 자바스크립트에서 중요한 요소를 배우기에 좋은 프로젝트 중 하나입니다. 배열과 객체, 이벤트 처리, 시간 제어, UI 등 코드를 한 줄씩 타이핑해보면서, 각 함수가 어떤 역할을 하는지 고민하다보면 금방 익숙해 질 수 있을 것입니다.

혹시 코드를 실행하는 중에 오류가 발생하거나, 추가하고 싶은 기능이 있다면 댓글로 남겨주세요.

Related

댓글 남기기