JavaScript로 구구단 퀴즈 만들기 — DOM, 버튼 클릭 등 기초적인 문법

JavaScript로 구구단 퀴즈 만들기 — DOM, 버튼 클릭 등 기초적인 문법 | Neujong

JavaScript로 구구단 퀴즈 만들기

구구단 퀴즈 예시 화면

단순한 구구단 암기가 아니라, 인터랙티브 퀴즈를 만들면서 자바스크립트의 핵심 로직(난수, 입력처리, 조건문, DOM 처리)을 실습해봅니다.
이 글은 기존에 적었던 여러 개의 글을 하나로 통합하여 작성한 완전 새로운 글로 초보자도 쉽게 따라하실 수 있도록 단계별로 구성했습니다.
숫자 키패드를 클릭, input 태그 입력, 기회 차감, 페이지 전환 등의 기능을 포함하고 있어 실제로 적용할 수 있는 작은 프로젝트 만들기를 지향하고 있습니다.

핵심 설계 요약

  • 문제는 2단부터 9단 사이에서 무작위로 생성
  • 사용자 입력을 받아 정답 여부 판단
  • 기회 차감을 통해 진짜 게임 같은 기능 추가
  • input 태그와 숫자 버튼의 상호작용
  • css를 통한 화면 전환 효과

1. 화면 구성(HTML)

HTML 구조는 간단합니다.
시작 페이지 - 메인 페이지 - 결과 페이지로 구분 지어서 작성했습니다.
시작 페이지에는 제목과 시작 버튼이 있고, 메인 페이지에는 구구단 문제, 숫자 패드, 숫자 출력창, 정답 확인 버튼으로 구성되어 있습니다.
결과 페이지에는 게임 결과와 다시 시작할 수 있는 버튼이 존재합니다.
페이지 전환은 css - display:none으로 적용하였습니다.

구구단 퀴즈 HTML 코드

2. 문제 생성 로직 (JavaScript)

  • 2단부터 9단까지 중에서 랜덤으로 문제가 출제되어야 합니다.
  • 현재 출제되었던 문제가 다음에 다시 출제되지 않도록 해야됩니다.
  • 처음에는 두 개의 숫자와 곱셈 기호만 보여주도록 합니다.
        
          // 구구단 문제 set 함수
          function setMultiplicationTablefunc() {
              start = 0;
              end = 0;
              correct = 0;

              start = Math.floor(Math.random() * 8) + 2;
              end = Math.floor(Math.random() * 8) + 2;

              correct = start * end;

              quiz.innerHTML = start + " x " + end;
          }
        
      

3. 정답 검사와 기회 차감 처리

사용자가 숫자 버튼을 통해서 숫자를 입력한 후에 정답 확인 버튼을 누르면 정답 검사를 시작합니다. 사용자가 정답 확인 버튼을 누르면 두 개의 숫자와 곱셈 기호 그리고 정답까지 보여지도록 합니다. 정답일 경우에는 다음 문제로 넘어가고, 오답일 경우에는 다시 문제를 풀도록 합니다. 사용자가 입력한 답이 오답이면 기회가 하나 차감되도록 합니다.

        
          checkBtn.addEventListener('click', function() {
          	setTimeout(function() {
              if(enteredNum.innerHTML === "") {
                  alert("정답을 눌러주세요!");
              } else {
                  if(chkOrNext === "check") {
                      if(correct === parseInt(inputNum)) {
                          checkingFunc("정답");

                          checkBtn.innerHTML = "다음 문제";
                          chkOrNext = "next";

                          for(let i=0; i<quizSubBtnList.length; i++) {
                              quizSubBtnList[i].disabled = true;
                          }
                      } else {
                          checkingFunc("오답");

                          inputNum = "";
                          enteredNum.innerHTML = inputNum;
                          setTimeout(() => {
                              quiz.innerHTML = "";
                              quiz.innerHTML = start + " x " + end;
                          }, 1500);
                          lifeCount--;
                          life.innerHTML = "🧡 x " + lifeCount;
                          if(lifeCount < 1) {
                              alert("처음부터 다시 시작합니다!");
                              retryFunc();
                          }
                      }
                  } else if(chkOrNext === "next") {
                      checkBtn.innerHTML = "정답 확인";
                      chkOrNext = "check";
                      inputNum = "";
                      enteredNum.innerHTML = inputNum;

                      for(let i=0; i<quizSubBtnList.length; i++) {
                          quizSubBtnList[i].disabled = false;
                      }

                      setQuizFunc();
                  }
              }
            }, 700);
          });
        
      
Note: 짧은 지연(700ms)은 사용자 경험을 개선합니다 — 정답 알림을 확인하고 다음 문제로 자연스럽게 넘어갑니다.

4. 초기화 함수

처음 시작을 할 때나 게임을 다시 시작 할 때마다 변수들을 초기화 해주어야 합니다.
그 때마다 변수를 계속 적으면 코드도 길어지고 복잡해지기 때문에 따로 함수로 만들어 놓으면 편하게 재사용할 수 있습니다.

        
          // 초기화 함수
          function init() {
              count = 0;
              lifeCount = 3;
              quizNumber.innerHTML = "구구단 퀴즈";
              quiz.innerHTML = "퀴즈를 시작해 볼까요?";
              life.style.display = "none";
              chapter = "start";
              chkOrNext = "check";
          }
        
      

5. 페이지 전환 - CSS 활용

시작 페이지 - 메인 페이지 - 결과 페이지를 전환할 때 각각의 페이지를 만들어서 전환할 수 도 있지만, 구구단 퀴즈처럼 프로젝트 규모가 크지 않다면 CSS를 활용해서 화면을 보였다 안보였다로 전환하는 느낌을 줄 수 있습니다. display: none 클래스를 하나 만들어 놓고, classList.toggle()를 활용합니다.

        
          // 다시 시작하는 함수
          function retryFunc() {
              switch(chapter) {
                  case "quiz":
                      startBtnClassName.classList.toggle("hidden");
                      quizBtnClassName.classList.toggle("hidden");
                      break;
                  case "result":
                      startBtnClassName.classList.toggle("hidden");
                      retryBtnClassName.classList.toggle("hidden");
                      break;
                  default:
                      break;
              }

              init();
          }
        
      

6. UI/UX 개선 포인트

  • 명확한 피드백(정답/오답/타이머) — 사용자 체류시간 증가
  • 이미지·아이콘 사용(예: 숫자 아이콘) — 시각적 신뢰도 향상
  • 모바일 친화적 버튼 크기 — 모바일 트래픽에 유리
  • 접근성: 버튼에 aria-label 추가

7. 디버깅과 자주 하는 실수

구구단 퀴즈를 만들면서 했던 흔한 실수는 문제와 입력의 타입(문자열 vs 숫자) 불일치였습니다. 항상 Number()로 형변환 후 비교하세요.
혹시 추가적으로 setTimeout을 사용하여 타이머를 추가하였다면 중복 실행되지 않도록 기존 interval을 clearInterval()로 정리하면 해결됩니다.

8. 확장 아이디어

  • 문제 출제 방식을 CSV/JSON으로 외부화해 콘텐츠 관리
  • 음성 출력(웹음성 API)으로 발음 학습 기능 추가
  • 난이도 조절 추가
  • 점수 기능 추가
  • 서버에 점수 저장(간단한 백엔드 + 랭킹 시스템)
  • 9단 이상의 문제도 추가

9. 마무리 — 학습 포인트 정리

이 프로젝트를 통해 배운 핵심은 무작위 생성, 입력 검증, DOM 처리, 버튼 클릭 리스너 활용, CSS 적용 등입니다.
또한 작은 인터랙티브 웹앱을 완성하면서 사용자 경험(피드백, UI 배치)을 고려하는 습관을 들이면 실제 서비스 개발에 큰 도움이 됩니다.
복잡한 프로그램 뿐만아니라 단순하지만 하나씩 만들다보면 포트폴리오도 늘려 나갈 수 있습니다.

구구단 퀴즈 실행 영상

구구단 퀴즈 실행 화면

이 글이 도움이 되셨다면 댓글로 개선 아이디어나 추가 기능 요청을 남겨주세요.
필요하면 이 구구단 퀴즈의 전체 소스 파일(.zip)과 데모 HTML을 제공해 드립니다.

댓글 쓰기

다음 이전