Skip to content

jinhomun/QuizEffect

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

9 Commits
 
 
 
 

Repository files navigation

QuizEffect

객관식과 주관식의 유형의 퀴즈를 만들어보았고, JSON파일의 데이터를 출력하는 방법을 배웠습니다.

Method

  • 변수 : 변수는 데이터를 저장하거나 참조하기 위한 메모리 공간의 이름이다.
  • 배열 : 동일한 데이터 형식의 요소들을 순서대로 저장하는 자료 구조이다.
  • 객체 : key-value 쌍으로 구성된 데이터를 저장하는 자료 구조로, 각 key는 고유한 식별자이며, 이에 대응하는 value는 해당 key와 연관된 데이터를 담고 있다.
  • 익명 함수 : 이름이 없는 함수로, 변수에 할당하여 사용되며 주로 즉시 실행 함수나 콜백 함수 등에서 활용된다.
  • 매개변수 함수 : 다른 함수에 전달되거나 호출될 때 입력값을 받아들이는 함수이다.
  • 화살표 함수 : ES6에서 도입된 함수 표현식의 간결한 형태로, 함수를 선언하는 데 사용되며 this의 동작 방식이 일반 함수와 다르다.
  • querySelector() : 문서 객체 모델에서 특정 CSS 선택자에 해당하는 첫 번째 요소를 반환하는 메서드입니다.
  • querySelectorAll() : 문서 내에서 특정 CSS 선택자에 해당하는 모든 요소를 NodeList로 반환하는 메서드입니다.
  • innerText : DOM에서 특정 HTML 요소의 텍스트 콘텐츠를 읽거나 설정하는 속성입니다.
  • classList.add() : 특정 HTML 요소의 클래스 목록에 새로운 클래스를 추가합니다.
  • classList.remove() : 특정 HTML 요소의 클래스 목록에서 지정된 클래스를 제거합니다.
  • addEventListener() : HTML 요소에 이벤트를 감지하고 해당 이벤트가 발생했을 때 실행할 함수를 등록하는 메서드입니다.
  • for(): 일반적인 반복문으로, 배열이나 객체 등의 iterable한 자료구조를 반복하며 코드 블록을 실행합니다.
  • forEach() : 배열의 각 요소에 대해 콜백 함수를 실행하는 배열 메서드입니다. 반복문의 초기화, 조건, 증가 부분을 명시하지 않고, 대신에 각 요소에 대한 로직을 콜백 함수로 전달하여 사용합니다.
    forEach()는 보다 간결하고 함수형 프로그래밍 스타일에 부합하는 반면, for()는 반복문의 세부 사항을 직접 제어할 수 있어 더 유연한 사용이 가능합니다.
  • 다중 if 문 : 여러 개의 조건문을 순차적으로 평가하고, 첫 번째로 참이 되는 조건문의 블록을 실행하는 JavaScript 제어 구조입니다.
  • textContent() : DOM 요소의 속성 중 하나로, 해당 요소의 텍스트 내용을 가져오거나 설정하는 데 사용되는 속성입니다.
  • trim() : 문자열의 양 끝에서 공백을 제거하는 메서드입니다.
  • toLowerCase() : 문자열의 모든 문자를 소문자로 변환하는 메서드입니다.
  • alert() : 브라우저에서 간단한 알림 창을 표시하는 JavaScript 함수입니다.
  • break() : 반복문이나 switch 문에서 실행을 중단하고 해당 블록을 빠져나오는 JavaScript 키워드입니다.
  • join(): 배열의 모든 요소를 문자열로 결합하여 반환하는 메서드입니다.
  • push(): 배열의 끝에 하나 이상의 요소를 추가하고, 배열의 새로운 길이를 반환하는 메서드입니다.

QuizEffect01 & QuizEffect02

Main
 <main id="main">
        <div class="quiz__wrap">
            <div class="quiz">
                <div class="quiz__header">
                    <span class="quiz__date"></span>  // 시험년도
                    <span class="quiz__type"></span>  // 시험과목  
                </div>
                <div class="quiz__main">
                    <div class="quiz__question">
                       <em></em>.  // 문제번호
                       <span></span> // 문제내용
                    </div>

                    <div class="quiz__animation">   // 퀴즈 애니메이션 
                        <div class="wrapper">
                            <div class="card-container">
                                <div class="dog">
                                    <div class="head">
                                        <div class="ears"></div>
                                        <div class="face"></div>
                                        <div class="eyes">
                                            <div class="teardrop"></div>
                                        </div>
                                        <div class="nose"></div>
                                        <div class="mouth">
                                            <div class="tongue"></div>
                                        </div>
                                        <div class="chin"></div>
                                    </div>
                                    <div class="body">
                                        <div class="tail"></div>
                                        <div class="legs"></div>
                                    </div>
                                </div>
                            </div>
                        </div>
                    </div>

                    <div class="quiz__input">
                        <input type="text" placeholder="정답을 입력해주세요!">  // 정답 입력 
                    </div>
                    <div class="quiz__answer"></div> // 정답
                    <div class="quiz__desc"></div>  // 정답에 대한 해설
                </div>
                <div class="quiz__footer">
                    <button class="quiz__confirm">정답 확인하기</button> // 정답 확인하기 버튼
                </div>
            </div>
        </div>
    </main>
    <!-- //main -->
QuizEffect01 - Script
1. 문제 정보 및 선택자 정의: infoDate, infoType, infoNum, infoQuestion, infoAnswer, infoDesc: 문제 정보를 담고 있는 변수들.
각각의 정보를 웹 페이지에서 특정 요소에 출력하기 위한 선택자들을 정의합니다.
예를 들어: quizDate = quizWrap.querySelector(".quiz__date"): 이 코드는 quizWrap 내에서 클래스가 "quiz__date"인 첫 번째 자식 요소를 찾아 quizDate 변수에 할당합니다.

2. 문제 출력: 각 선택자를 사용하여 문제 정보를 웹 페이지에 출력합니다.
innerText는 자식 요소의 숨겨진 텍스트를 포함하여 텍스트 콘텐츠를 반환합니다.

3. 정답 해설 숨기기: 초기에 정답과 해설을 숨기기 위해 해당 요소들에 none 클래스를 추가합니다.

4. 정답 확인하기: 정답 확인 버튼(quizConfirm)에 이벤트 리스너를 등록합니다.
사용자가 입력한 답(quizInput.value)과 정답(infoAnswer)을 비교하여, 맞으면 like 애니메이션을, 틀리면 dislike 애니메이션을 적용합니다.
정답과 해설을 나타내는 요소들을 화면에 표시하고, 정답 입력을 받는 입력란과 정답 확인 버튼을 숨깁니다.

<script>
        // 문제 정보
        const  infoDate ="2021년 10월";         // infoDate : 정보날짜
        const  infoType ="정보처리 기능사";     //  infoType : 정보유형   
        const  infoNum = "1";                 //  infoNum : 문제 번호
        const  infoQuestion = "CPU의 정보처리 속도 단위 중 초당 100만 개의 연산을 수행한다는 의미의 단위는?" // infoQuestion: 문제이름
        const  infoAnswer = "MIPS"            // infoAnswer: 문제 정답
        const  infoDesc =  "LIPS는 초당 1개, KIPS는 초당 1000개, MIPS는 초당 1000000의 연산을 수행하는 것을 의미합니다." // infoDesc: 문제 해설

        // 선택자
        const quizWrap = document.querySelector(".quiz__wrap");
        const quizDate = quizWrap.querySelector(".quiz__date");
        const quizType = quizWrap.querySelector(".quiz__type");
        const quizNum = quizWrap.querySelector(".quiz__question em");
        const quizQuestion = quizWrap.querySelector(".quiz__question span");
        const quizAnswer = quizWrap.querySelector(".quiz__answer");
        const quizDesc = quizWrap.querySelector(".quiz__desc");
        const quizConfirm = quizWrap.querySelector(".quiz__confirm");
        const quizInput = quizWrap.querySelector(".quiz__input input");
        const quizAnimation = quizWrap.querySelector(".quiz__animation");

        // 문제 출력
        quizDate.innerText = infoDate;
        quizType.innerText = infoType;
        quizNum.innerText = infoNum;
        quizQuestion.innerText = infoQuestion ;
        quizAnswer.innerText = infoAnswer;
        quizDesc.innerText = infoDesc;

        // 정답 해설 숨기기
        quizAnswer.classList.add("none");
        quizDesc.classList.add("none");

        // 정답 확인하기
        quizConfirm.addEventListener("click", () => {
            const userAnswer = quizInput.value;

            if(infoAnswer == userAnswer){
                quizAnimation.classList.add("like");   
            }else {
                quizAnimation.classList.add("dislike");
            }
            quizAnswer.classList.remove("none");
            quizDesc.classList.remove("none");
            quizConfirm.classList.add("none");
            quizInput.classList.add("none");
        });
    </script>
QuizEffect02 - Script
1. HTML 요소 선택자 정의: quizWrap: HTML 문서 내의 클래스가 "quiz__wrap"인 요소를 선택합니다.
나머지 선택자들은 quizWrap 내에서 특정 클래스를 가진 하위 요소들을 모두 선택(querySelectorAll)합니다.

2. 퀴즈 정보 배열 생성: quizInfo 배열은 각 퀴즈의 정보를 객체 형태로 가지고 있습니다.
각 객체는 퀴즈의 날짜, 유형, 번호, 문제, 정답, 해설을 포함합니다.

3. 반복문을 사용한 HTML 동적 생성: for문을 사용하여 quizInfo 배열의 각 요소를 반복하면서 해당 정보를 HTML 문서 내의 퀴즈 요소에 동적으로 할당합니다.

4. forEach 메서드를 사용한 HTML 동적 생성: forEach 메서드를 사용하여도 마찬가지로 배열의 각 요소를 반복하면서 HTML 동적 생성을 수행합니다
forEach 메서드는 for문보다 코드가 더 간결하고 함수형 프로그래밍 스타일을 지원하므로, 일부 개발자는 forEach를 선호합니다.

5. 퀴즈 정답과 해설 숨기기: forEach 메서드를 사용하여 모든 퀴즈의 정답과 해설을 처음에는 화면에서 숨깁니다.

6. 정답 확인 이벤트 등록: forEach 메서드를 사용하여 각 정답 확인 버튼(quizConfirm)에 클릭 이벤트를 등록합니다.
클릭 시, 사용자가 입력한 답과 실제 정답을 비교하여 알맞은 피드백 애니메이션을 적용하고, 정답과 해설을 화면에 표시하며 입력란과 확인 버튼을 숨깁니다.

```js <script> // 선택자 const quizWrap = document.querySelector(".quiz__wrap"); const quizDate = quizWrap.querySelectorAll(".quiz__date"); const quizType = quizWrap.querySelectorAll(".quiz__type"); const quizNum = quizWrap.querySelectorAll(".quiz__question em"); const quizQuestion = quizWrap.querySelectorAll(".quiz__question span"); const quizAnswer = quizWrap.querySelectorAll(".quiz__answer"); const quizDesc = quizWrap.querySelectorAll(".quiz__desc"); const quizConfirm = quizWrap.querySelectorAll(".quiz__confirm"); const quizInput = quizWrap.querySelectorAll(".quiz__input input"); const quizAnimation = quizWrap.querySelectorAll(".quiz__animation");
    // 문제정보
    const quizInfo = [
        {
            infoDate:"2019년 상시",
            infoType:"정보처리기능사",
            infoNum :"1",
            infoQuestion:"현재 수행 중에 있는 명령어 코드(code)를 저장하고 있는 임시 저장 장치는?",
            infoAnswer:"명령 레지스터",
            infoDesc:"명령 레지스터(IR)는 현재 수행 중인 명령어를 보관"
        } , 
        {
            infoDate:"2020년 4회",
            infoType:"정보처리 기능사",
            infoNum :"2",
            infoQuestion:"1비트(bit)를 기억할 수 있는 능력을 가진 기억의 최소단위로 클록이 있는 순서 회로에 기억된 기억 소자는?",
            infoAnswer:"플립플롭",
            infoDesc:"플립플롭은  1비트('0' 또는 '1')의 정보를 기억할 수 있는 최소의 기억 소자로 RS 플립플롭, JK 플립플롭, D플립플롭, T플립플롭 등이 있음"
        },
        {
            infoDate:"2021년 1회",
            infoType:"정보처리 기능사",
            infoNum :"3",
            infoQuestion:"누를 때마다 ON, OFF가 교차되는 스위치를 만들고자 할 때 사용되는 플립플롭은?",
            infoAnswer:"T 플립플롭",
            infoDesc:"입력이 '0'이면 전 상태 불변, 입력이 '1'이면 전 상태의 보수값"
        } 

    ];

    //  for()
    for(let i=0; i<quizInfo.length; i++){
        quizDate[i].textContent = quizInfo[i].infoDate;
        quizType[i].textContent = quizInfo[i].infoType;
        quizNum[i].textContent = quizInfo[i].infoNum;
        quizQuestion[i].textContent = quizInfo[i].infoQuestion;
        quizAnswer[i].textContent = quizInfo[i].infoAnswer;
        quizDesc[i].textContent = quizInfo[i].infoDesc;
    }

    // forEach()
    quizInfo.forEach((el,i) => {
        quizDate[i].textContent = quizInfo[i].infoDate;
        quizType[i].textContent = quizInfo[i].infoType;
        quizNum[i].textContent = quizInfo[i].infoNum;
        quizQuestion[i].textContent = quizInfo[i].infoQuestion;
        quizAnswer[i].textContent = quizInfo[i].infoAnswer;
        quizDesc[i].textContent = quizInfo[i].infoDesc;
    });

  
    
    // forEach()
    quizInfo.forEach((el,i) => {
        quizAnswer[i].style.display = "none";
        quizDesc[i].style.display = "none";
    });

    // 정답확인
    quizConfirm.forEach(function(btn, num){
        btn.addEventListener("click", function(){
            const userAnswer = quizInput[num].value;
           
            if(userAnswer === quizInfo[num].infoAnswer){
                quizAnimation[num].classList.add("like");
            }else {
                quizAnimation[num].classList.add("dislike");
            }
            quizAnswer[num].style.display ="block";
            quizDesc[num].style.display = "block";
            quizConfirm[num].style.display = "none";
            quizInput[num].style.display = "none"; 
        });
    });      
</script> ```

QuizEffect03 & QuizEffect04

Main
<main id="main">
        <div class="quiz__wrap">
            <div class="quiz">
                <div class="quiz__header"></div>   // 문제 년도 & 과목
                <div class="quiz__main">
                    <div class="quiz__question"></div> // 문제 내용
                    <div class="quiz__choice">  // 객관식(4지선다형)
                        <label for="choice1">
                            <input type="radio" id="choice1" name="choice" value="1">
                            <span></span>
                        </label>
                        <label for="choice2">
                            <input type="radio" id="choice2" name="choice" value="2">
                            <span></span>
                        </label>
                        <label for="choice3">
                            <input type="radio" id="choice3" name="choice" value="3">
                            <span></span>
                        </label>
                        <label for="choice4">
                            <input type="radio" id="choice4" name="choice" value="4">
                            <span></span>
                        </label>
                    </div>
                    <div class="quiz__answer none"></div>  // 정답
                    <div class="quiz__desc none"></div>   // 해설
                </div>
                <div class="quiz__footer">
                    <button class="quiz__confirm">정답 확인하기</button> // 정답 버튼
                </div>
            </div>
        </div>
    </main>
    <!-- //main -->
QuizEffect03 - Script
1. 문제 정보 및 선택자 정의: infoDate, infoType, infoNum, infoQuestion, infoChoice, infoAnswer, infoDesc: 문제 정보를 담고 있는 변수들.
각각의 정보를 웹 페이지에서 특정 요소에 출력하기 위한 선택자들을 정의합니다.
예를 들어: quizDate = quizWrap.querySelector(".quiz__date"): 이 코드는 quizWrap 내에서 클래스가 "quiz__date"인 첫 번째 자식 요소를 찾아 quizDate 변수에 할당합니다.

2. 퀴즈 정보 배열 생성: quizInfo 배열은 각 퀴즈의 정보를 객체 형태로 가지고 있습니다.
각 객체는 퀴즈의 날짜, 유형, 번호, 문제, 정답, 해설을 포함합니다.

3. 문제 출력: for 루프를 사용하여 quizInfo의 정보를 HTML 요소에 동적으로 적용합니다. 퀴즈의 제목, 질문, 선택지 등이 화면에 표시됩니다.

4. 정답 확인: 정답 확인 버튼을 클릭하면 선택된 선택지의 값을 확인하여 정답 여부를 판단합니다.
선택된 값이 정답과 일치하면 정답 메시지를 표시하고, 그렇지 않으면 오답 메시지와 함께 정답과 설명을 표시합니다.
선택지를 선택하지 않은 경우 경고 메시지를 표시합니다.

5. CSS 클래스 조작: 퀴즈의 정답과 설명은 초기에 화면에서 숨겨져 있습니다. 정답 확인 시에 해당 내용을 표시하기 위해 CSS 클래스(none)를 추가 및 제거합니다.

   <script>
        // 선택자
        const quizWrap = document.querySelector(".quiz__wrap");
        const quizHeader = quizWrap.querySelector(".quiz__header")
        const quizQuestion = quizWrap.querySelector(".quiz__question");
        const quizAnswer = quizWrap.querySelector(".quiz__answer");
        const quizDesc = quizWrap.querySelector(".quiz__desc");
        const quizChoice = quizWrap.querySelectorAll(".quiz__choice span");
        const quizSelect = quizWrap.querySelectorAll(".quiz__choice input");
        const quizConfirm = quizWrap.querySelector(".quiz__confirm");

        // 문제정보
        const quizInfo = [
            {
                infoDate : "2016년 4회",
                infoType : "웹디자인 기능사",
                infoNum : "01",
                infoQuestion : "다음 중 디자인의 기본 요소들로 옳은 것은?",
                infoChoice : ["선, 색채, 공간, 수량", "점, 선, 면, 질감", "시간, 수량, 구조, 공간", "면, 구조, 공간, 수량"],
                infoAnswer : "2",
                infoDesc : "디자인의 기본 요소에는 점, 선, 면, 질감이 있습니다."
            }
        ];
    
        // 문제출력
        for(let i=0; i< quizInfo.length; i++){
            quizHeader.innerHTML = quizInfo[i].infoDate + " " + quizInfo[i].infoType;
            quizQuestion.innerHTML = quizInfo[i].infoNum + ". " + quizInfo[i].infoQuestion;
            quizAnswer.innerText = quizInfo[i].infoAnswer;
            quizDesc.innerText = quizInfo[i].infoDesc;

            for(let j=0; j< quizChoice.length; j++){
                quizChoice[j].innerText = quizInfo[i].infoChoice[j];
            }
        }
        
        // 정답 확인
        quizConfirm.addEventListener("click", () => {
            let selectedChoice = null;

            for(i=0; i<quizSelect.length; i++){
                if(quizSelect[i].checked){
                    selectedChoice = quizSelect[i].value;
                    break;
                }
            }

            if(selectedChoice !== null){
                if(selectedChoice == quizInfo[0].infoAnswer){
                    alert("정답입니다.");
                    quizDesc.classList.remove("none");
                } else {
                    alert("오답입니다.");
                    quizAnswer.classList.remove("none");
                    quizDesc.classList.remove("none");
                }
            } else {
                alert("보기를 선택하세요!😂");
            }
        });

    </script>
QuizEffect04 - Script
1. 선택자 정의 : document.querySelector 및 document.querySelectorAll를 사용하여 HTML 문서에서 퀴즈와 관련된 요소들을 선택합니다.

2. 문제 정보 정의 : quizInfo 배열에 퀴즈 정보를 객체 형태로 저장합니다. 날짜, 유형, 번호, 질문, 정답, 설명 등의 정보가 포함됩니다.

3. 문제 출력 : for 루프를 사용하여 quizDate, quizType, quizNum, quizQuestion, quizAnswer, quizDesc 등의 요소에 퀴즈 정보를 적절히 출력합니다.

4. forEach()를 활용한 동일한 작업 : forEach를 사용하여 퀴즈 정보를 출력하는 부분이 중복되는 부분을 더 간결하게 작성합니다.

5. 정답 숨기기 : forEach를 사용하여 정답과 설명을 숨기는 작업을 수행합니다.

6. 정답 확인 및 애니메이션 적용 : quizConfirm 버튼에 대해 forEach를 사용하여 각 버튼에 이벤트 리스너를 추가합니다.
사용자가 입력한 답안과 정답을 비교하고, 그에 따라 애니메이션을 적용하여 피드백을 제공합니다.
정답 및 설명을 표시하고, 입력과 버튼을 숨기는 등의 동작을 수행합니다.

<script>
       // 선택자
        const quizWrap = document.querySelector(".quiz__wrap");
        const quizDate = quizWrap.querySelectorAll(".quiz__date");
        const quizType = quizWrap.querySelectorAll(".quiz__type");
        const quizNum = quizWrap.querySelectorAll(".quiz__question em");
        const quizQuestion = quizWrap.querySelectorAll(".quiz__question span");
        const quizAnswer = quizWrap.querySelectorAll(".quiz__answer");
        const quizDesc = quizWrap.querySelectorAll(".quiz__desc");
        const quizConfirm = quizWrap.querySelectorAll(".quiz__confirm");
        const quizInput = quizWrap.querySelectorAll(".quiz__input input");
        const quizAnimation = quizWrap.querySelectorAll(".quiz__animation");

        // 문제정보
        const quizInfo = [
            {
                infoDate:"2019년 상시",
                infoType:"정보처리기능사",
                infoNum :"1",
                infoQuestion:"현재 수행 중에 있는 명령어 코드(code)를 저장하고 있는 임시 저장 장치는?",
                infoAnswer:"명령 레지스터",
                infoDesc:"명령 레지스터(IR)는 현재 수행 중인 명령어를 보관"
            } , 
            {
                infoDate:"2020년 4회",
                infoType:"정보처리 기능사",
                infoNum :"2",
                infoQuestion:"1비트(bit)를 기억할 수 있는 능력을 가진 기억의 최소단위로 클록이 있는 순서 회로에 기억된 기억 소자는?",
                infoAnswer:"플립플롭",
                infoDesc:"플립플롭은  1비트('0' 또는 '1')의 정보를 기억할 수 있는 최소의 기억 소자로 RS 플립플롭, JK 플립플롭, D플립플롭, T플립플롭 등이 있음"
            },
            {
                infoDate:"2021년 1회",
                infoType:"정보처리 기능사",
                infoNum :"3",
                infoQuestion:"누를 때마다 ON, OFF가 교차되는 스위치를 만들고자 할 때 사용되는 플립플롭은?",
                infoAnswer:"T 플립플롭",
                infoDesc:"입력이 '0'이면 전 상태 불변, 입력이 '1'이면 전 상태의 보수값"
            } 

        ];

        //  for()
        for(let i=0; i<quizInfo.length; i++){
            quizDate[i].textContent = quizInfo[i].infoDate;
            quizType[i].textContent = quizInfo[i].infoType;
            quizNum[i].textContent = quizInfo[i].infoNum;
            quizQuestion[i].textContent = quizInfo[i].infoQuestion;
            quizAnswer[i].textContent = quizInfo[i].infoAnswer;
            quizDesc[i].textContent = quizInfo[i].infoDesc;
        }

        // forEach()
        quizInfo.forEach((el,i) => {
            quizDate[i].textContent = quizInfo[i].infoDate;
            quizType[i].textContent = quizInfo[i].infoType;
            quizNum[i].textContent = quizInfo[i].infoNum;
            quizQuestion[i].textContent = quizInfo[i].infoQuestion;
            quizAnswer[i].textContent = quizInfo[i].infoAnswer;
            quizDesc[i].textContent = quizInfo[i].infoDesc;
        });

      
        
        // forEach()
        quizInfo.forEach((el,i) => {
            quizAnswer[i].style.display = "none";
            quizDesc[i].style.display = "none";
        });

        // 정답확인
        quizConfirm.forEach(function(btn, num){
            btn.addEventListener("click", function(){
                const userAnswer = quizInput[num].value;
               
                if(userAnswer === quizInfo[num].infoAnswer){
                    quizAnimation[num].classList.add("like");
                }else {
                    quizAnimation[num].classList.add("dislike");
                }
                quizAnswer[num].style.display ="block";
                quizDesc[num].style.display = "block";
                quizConfirm[num].style.display = "none";
                quizInput[num].style.display = "none"; 
            });
        });      
</script>

QuizEffect05 & QuizEffect06(Json)

Main
<main id="main">
        <div class="quiz__wrap"></div>
</main>
    <!-- //main -->   
 <main id="main">
        <div class="quiz__wrap"></div>
        <div class="quiz__check">정답 확인</div>
</main>
<!-- //main -->
QuizEffect05 - Script
1. 선택자 정의 : document.querySelector를 사용하여 HTML 문서에서 퀴즈와 관련된 요소를 선택합니다.

2. 문제 정보 정의 : quizInfo 배열에 퀴즈 정보를 객체 형태로 저장합니다. 날짜, 유형, 질문, 선택지, 정답, 설명 등의 정보가 포함됩니다.

3. updateQuiz 함수 : 이 함수는 특정 인덱스의 퀴즈 정보를 받아와 해당 퀴즈의 HTML을 동적으로 생성하고, 페이지에 출력합니다.
퀴즈의 헤더(날짜와 유형), 메인 부분(문제, 선택지, 정답, 설명), 푸터(정답 확인과 다음 문제로 이동 버튼)으로 구성됩니다.
템플릿 문자열을 사용하여 동적으로 HTML을 생성합니다.

4. 정답 확인 함수 (checkAnswer) : 사용자가 선택한 답과 정답을 비교하여 피드백을 제공합니다.
선택한 답이 없을 경우 알림을 표시합니다.

5. 페이지 로드 후 초기화 : DOMContentLoaded 이벤트를 사용하여 페이지 로드가 완료되면 초기 퀴즈를 업데이트합니다.

 <script>
    //선택자
    const quizWrap = document.querySelector(".quiz__wrap");

    // 문제 정보
    const quizInfo = [
            {
                infoDate : "2006년 5회",
                infoType : "정보처리 기능사",
                infoQuestion : "이항(binary) 연산에 해당하는 것은?",
                infoChoice : ["COMPLEMENT","AND","ROTATE","SHIFT"],
                infoAnswer : "2",
                infoDesc : "단항연산 : ROTATE, SHIFT, MOVE, NOT(COMPLEMENT)"
            },
            {
                infoDate : "2006년 5회",
                infoType : "정보처리 기능사",
                infoQuestion : "프로그램이 컴퓨터의 기종에 관계없이 수행될 수 있는 성질을 의미하는 것은?",
                infoChoice : ["가용성","신뢰성","호환성","안전성"],
                infoAnswer : "3",
                infoDesc : "컴퓨터의 기종에 관계없이 동작하므로 호환성입니다. 호환성이란 까스활명수, 까스명수, 베아제등 이름은 틀리지만 소화제의 기능을 하는것처럼 기종에 관계없이 동작할수 있는 것들을 말합니다."
            },
            {
                infoDate : "2006년 5회",
                infoType : "정보처리 기능사",
                infoQuestion : "제어장치가 앞의 명령 실행을 완료한 후, 다음에 실행 할 명령을 기억장치로부터 가져오는 동작을 완료할 때까지의 주기를 무엇이라고 하는가?",
                infoChoice : ["fetch cycle","transfer cycle","search time","run time"],
                infoAnswer : "1",
                infoDesc : "명령어를 가지고 오는것을 fetch cycle 이라고 합니다."
            }
        ];
                
    let currentIndex = 0;  // 현재 문제 변수 값(현재 풀고 있는 값)
    // 문제출력
    const updataQuiz = (index) => {
        let quizWrapTag = `
            <div class="quiz">
                <div class="quiz__header">${quizInfo[index].infoDate} ${quizInfo[index].infoType}</div>
                <div class="quiz__main">
                    <div class="quiz__question">${index+1}. ${quizInfo[index].infoQuestion}</div>
                    <div class="quiz__choice">
                        <label for="choice1">
                            <input type="radio" id="choice1" name="choice" value="1">
                            <span>${quizInfo[index].infoChoice[0]}</span>
                        </label>
                        <label for="choice2">
                            <input type="radio" id="choice2" name="choice" value="2">
                            <span>${quizInfo[index].infoChoice[1]}</span>
                        </label>
                        <label for="choice3">
                            <input type="radio" id="choice3" name="choice" value="3">
                            <span>${quizInfo[index].infoChoice[2]}</span>
                        </label>
                        <label for="choice4">
                            <input type="radio" id="choice4" name="choice" value="4">
                            <span>${quizInfo[index].infoChoice[3]}</span>
                        </label>
                    </div>
                    <div class="quiz__answer none">${quizInfo[index].infoAnswer}
                    </div>
                    <div class="quiz__desc none">${quizInfo[index].infoDesc}
                    </div>
                </div>
                <div class="quiz__footer">
                    <button class="quiz__confirm">정답 확인하기</button>
                    <button class="quiz__next none">다음 문제</button>
                </div>
            </div>
        `;
        quizWrap.innerHTML = quizWrapTag;

        
        // 선택자
        const quizConfirm = quizWrap.querySelector(".quiz__confirm");
        const quizNext = quizWrap.querySelector(".quiz__next");
        
        // 정답 확인 버튼
        quizConfirm.addEventListener("click", () => {
            checkAnswer();
            quizConfirm.classList.add("none");   // 정답 버튼 삭제
            quizNext.classList.remove("none");   // 다음 버튼 추가
        });

        // 다음 문제 버튼
        quizNext.addEventListener("click", () => {
            if(currentIndex < quizInfo.length -1){
                quizNext.classList.add("none");         // 다음 버튼 삭제
                quizConfirm.classList.remove("none");   // 정답 버튼 추가
                currentIndex++;                         // 문제 번호 추가
            updataQuiz(currentIndex);                   //퀴즈 반영
            }else {
                alert("퀴즈가 종료되었습니다.");
            }
        });
    };

    // 정답 확인
    const checkAnswer = () => {
        const selectedChoice = quizWrap.querySelector("input[name='choice']:checked");
        
        if(!selectedChoice){
            alert("답을 선택해주세요");
        };
        
        const userAnswer = selectedChoice.value;                    // 사용자가 클릭한 정답
        const corrcetAnswer = quizInfo[currentIndex].infoAnswer;   //정답지의 정답
        const quizElement = quizWrap.querySelector(".quiz");
        const descElement = quizWrap.querySelector(".quiz__desc");
        const answerElement = quizWrap.querySelector(".quiz__answer");
        if(userAnswer === corrcetAnswer){
            quizElement.classList.add("good");
            descElement.classList.remove("none");
        } else {
            quizElement.classList.add("bad");
            answerElement.classList.remove("none");
            descElement.classList.remove("none");
        }
        descElement.classList.remove("none");
    };

    // 점수 업데이트
    const updateScore = () => {
        const scoreElement = document.querySelector(".quiz__score");
        scoreElement.textContent = quizScore; // 점수 업데이트
    }
    // 페이지가 로드된 후 실행
    document.addEventListener("DOMContentLoaded", () => {
        updataQuiz(currentIndex);
    });
    </script>
QuizEffect06 - Script
1. 선택자 및 초기화 : HTML 문서 내의 특정 클래스를 가진 요소들을 JavaScript로 선택하고, 퀴즈 정보 및 점수를 담을 변수들을 초기화합니다.


3. 퀴즈 출력 : updataQuiz 함수는 quizInfo 배열을 순회하면서 각 퀴즈를 HTML 형태로 구성하여 동적으로 화면에 출력합니다. 각 퀴즈는 선택지가 랜덤으로 섞여서 표시됩니다.

4. 정답 확인 및 점수 계산 : 사용자가 선택한 답을 확인하고, 맞으면 해당 퀴즈를 '정답'으로 표시하고 점수를 증가시킵니다.
틀린 경우에는 '오답'으로 표시하고 정답을 보여줍니다.

5. 최종 점수 알림 : 사용자가 모든 퀴즈에 대한 답을 확인한 후에는 총 맞은 갯수를 알리는 알림창이 뜨게 됩니다.

6. 페이지 로딩 후 실행 : DOMContentLoaded 이벤트가 발생하면 fetchQuiz 함수가 호출되어 초기 데이터를 가져와 퀴즈를 출력합니다.
       <script>
        // 선택자
        const quizWrap = document.querySelector(".quiz__wrap");
        const quizCheck = document.querySelector(".quiz__check");

        // 문제 정보
       let quizInfo = [];
       let quizScore = 0;

        // 문제 가져오기
        const fetchQuiz = () => {
            fetch("https://webstoryboy.github.io/webs2024/json/gineungsaJC2011_05.json")
            .then(res => res.json())
            .then(items => {
                quizInfo = items.map((item, idex) => {
                    const formattedQuiz = {
                        infoDate :"2011년 5회",
                        infoType : item.subject,
                        infoQuestion : item.question,
                        infoDesc : item.desc,
                        infoAnswer :item.correct_answer 
                    }
                    //보기 가져오기
                    const choices =[...item.incorrect_answers, item.correct_answer];

                     // 보기 랜덤 섞기
                     for (let i = choices.length - 1; i > 0; i--) {
                        const j = Math.floor(Math.random() * (i + 1));
                        [choices[i], choices[j]] = [choices[j], choices[i]];
                    }

                    formattedQuiz.infoChoice = choices;
                    return formattedQuiz;
                });
                console.log(quizInfo);
                updataQuiz();
            })
        }
        
        // 문제 출력
        const updataQuiz = () => {
            const quizArray = [];

            quizInfo.forEach((quiz, number) => {
                quizArray.push(`
                    <div class="quiz">
                        <div class="quiz__header">${quiz.infoDate} ${quiz.infoType}</div>
                        <div class="quiz__main">
                            <div class="quiz__question">
                                ${number+1}. ${quiz.infoQuestion}
                            </div>
                            <div class="quiz__choice">
                                <label for="choice1-${number}">
                                    <input type="radio" id="choice1-${number}" name="choice-${number}" value=${quiz.infoChoice[0]}>
                                    <span>${quiz.infoChoice[0]}</span>
                                </label>
                                <label for="choice2-${number}">
                                    <input type="radio" id="choice2-${number}" name="choice-${number}" value=${quiz.infoChoice[1]}>
                                    <span>${quiz.infoChoice[1]}</span>
                                </label>
                                <label for="choice3-${number}">
                                    <input type="radio" id="choice3-${number}" name="choice-${number}" value=${quiz.infoChoice[2]}>
                                    <span>${quiz.infoChoice[2]}</span>
                                </label>
                                <label for="choice4-${number}">
                                    <input type="radio" id="choice4-${number}" name="choice-${number}" value=${quiz.infoChoice[3]}>
                                    <span>${quiz.infoChoice[3]}</span>
                                </label>
                            </div>
                            <div class="quiz__answer none">${quiz.infoAnswer}</div>
                            <div class="quiz__desc none">${quiz.infoDesc}</div>
                        </div>
                    </div>
                `);
            })

            quizWrap.innerHTML = quizArray.join("");
        }

        // 정답 확인
        quizCheck.addEventListener("click", () => {
            const quizElements = document.querySelectorAll(".quiz");

            quizElements.forEach((quizElement, index) => {
                const selectedChoice = quizElement.querySelector(`input[name="choice-${index}"]:checked`);  //체크한 정답
                const quizAnswer = quizElement.querySelector(".quiz__answer");
                const quizDesc = quizElement.querySelector(".quiz__desc");

                if(selectedChoice){
                    const userAnswer = selectedChoice.value;
                    const correctAnswer = quizAnswer.textContent;

                    if(userAnswer === correctAnswer){
                        console.log("정답입니다.");
                        quizElement.classList.add("good");
                        quizDesc.classList.remove("none");
                        quizScore++;
                    } else {
                        console.log("오답입니다.");
                        quizElement.classList.add("bad");
                        quizAnswer.classList.remove("none");
                        quizDesc.classList.remove("none");
                    }
                }
            });

            alert("총 맞은 갯수는 : " + quizScore + "개 입니다.");
        });

        // 페이지가 로드된 후 실행
        document.addEventListener("DOMContentLoaded", () => {
            fetchQuiz();
        });

    </script>
Main
<main id="main">
       <div class="cbt__box">
            <h2>기능사 시험</h2>
            <select id="cbtSelect1">
                <option value="gineungsaJC2005_02">정보처리기능사 2005년 2회</option>
                <option value="gineungsaJC2005_04">정보처리기능사 2005년 4회</option>
                <option value="gineungsaJC2005_05">정보처리기능사 2005년 5회</option>
                <option value="gineungsaJC2006_01">정보처리기능사 2006년 1회</option>
                <option value="gineungsaJC2006_02">정보처리기능사 2006년 2회</option>
                <option value="gineungsaJC2006_03">정보처리기능사 2006년 3회</option>
                <option value="gineungsaJC2006_05">정보처리기능사 2006년 5회</option>
                <option value="gineungsaJC2007_01">정보처리기능사 2007년 1회</option>
                <option value="gineungsaJC2007_02">정보처리기능사 2007년 2회</option>
                <option value="gineungsaJC2007_04">정보처리기능사 2007년 4회</option>
                <option value="gineungsaJC2007_05">정보처리기능사 2007년 5회</option>
                <option value="gineungsaJC2008_01">정보처리기능사 2008년 1회</option>
                <option value="gineungsaJC2008_02">정보처리기능사 2008년 2회</option>
                <option value="gineungsaJC2008_04">정보처리기능사 2008년 4회</option>
                <option value="gineungsaJC2009_01">정보처리기능사 2009년 1회</option>
                <option value="gineungsaJC2009_04">정보처리기능사 2009년 4회</option>
                <option value="gineungsaJC2009_05">정보처리기능사 2009년 5회</option>
                <option value="gineungsaJC2010_02">정보처리기능사 2010년 2회</option>
                <option value="gineungsaJC2010_05">정보처리기능사 2010년 5회</option>
                <option value="gineungsaJC2011_01">정보처리기능사 2011년 1회</option>
                <option value="gineungsaJC2011_02">정보처리기능사 2011년 2회</option>
                <option value="gineungsaJC2011_04">정보처리기능사 2011년 4회</option>
                <option value="gineungsaJC2011_05">정보처리기능사 2011년 5회</option>
            </select>
            <select id="cbtSelect2">
                <option value="gineungsaWD2009_05">웹디자인기능사 2009년 1회</option>
                <option value="gineungsaWD2010_01">웹디자인기능사 2010년 1회</option>
                <option value="gineungsaWD2010_02">웹디자인기능사 2010년 2회</option>
                <option value="gineungsaWD2010_04">웹디자인기능사 2010년 4회</option>
                <option value="gineungsaWD2010_05">웹디자인기능사 2010년 5회</option>
                <option value="gineungsaWD2011_01">웹디자인기능사 2011년 1회</option>
                <option value="gineungsaWD2011_02">웹디자인기능사 2011년 2회</option>
                <option value="gineungsaWD2011_04">웹디자인기능사 2011년 4회</option>
                <option value="gineungsaWD2011_05">웹디자인기능사 2011년 5회</option>
                <option value="gineungsaWD2012_02">웹디자인기능사 2012년 2회</option>
                <option value="gineungsaWD2012_04">웹디자인기능사 2012년 4회</option>
                <option value="gineungsaWD2013_02">웹디자인기능사 2013년 2회</option>
                <option value="gineungsaWD2013_04">웹디자인기능사 2013년 4회</option>
                <option value="gineungsaWD2013_05">웹디자인기능사 2013년 5회</option>
                <option value="gineungsaWD2014_01">웹디자인기능사 2014년 1회</option>
                <option value="gineungsaWD2014_04">웹디자인기능사 2014년 4회</option>
                <option value="gineungsaWD2014_05">웹디자인기능사 2014년 5회</option>
                <option value="gineungsaWD2015_01">웹디자인기능사 2015년 1회</option>
                <option value="gineungsaWD2015_03">웹디자인기능사 2015년 3회</option>
                <option value="gineungsaWD2015_04">웹디자인기능사 2015년 4회</option>
                <option value="gineungsaWD2015_05">웹디자인기능사 2015년 5회</option>
                <option value="gineungsaWD2016_01">웹디자인기능사 2016년 1회</option>
                <option value="gineungsaWD2016_04">웹디자인기능사 2016년 4회</option>
            </select>
            <p>
                당신의 이름은 <input type="text" class="cbt__select__input"> 입니다. <br>
                <em class="cbt__select__title">정보처리기능사 2005년 2회</em> 문제를 선택했습니다. <br>
                시작하겠습니까?<br>
                총 시간은 60분이며, 60점 이상 맞아야 합격입니다.
            </p>
            <button class="cbt__box__start">시작하기</button>
       </div>
       <div class="cbt__wrap none">
        <div class="cbt__header">
            <h1  class="cbt__title">정보처리기능사 2005년 2회 기출문제</h1>
            <div class="cbt__time">남은시간 <span>60분 00초</span></div>
        </div>
        <!-- //cbt__header -->

        <div class="cbt__conts">
            <div class="cbt__quiz">
                
            </div>
        </div>
        <!-- //cbt__conts -->

        <div class="cbt__aside">
            <div class="cbt__name">수험자 : 문진호</div>
            <div class="cbt__submit">답안지 제출하기</div>
            <div class="cbt__giveup">포기하기</div>
            <div class="cbt__again none">다시 풀기</div>
            <div class="cbt__omr"></div>
        </div>
        <!-- //cbt__aside -->
    </div>
</main>
<!-- //main -->
QuizEffect07 - Script
1. 선택자 및 초기화 : HTML 문서 내의 특정 클래스 및 요소들을 JavaScript로 선택하고, 필요한 변수들을 초기화합니다.

2. 퀴즈 데이터 가져오기 : 사용자가 선택한 옵션에 따라 외부 JSON 파일에서 퀴즈 데이터를 비동기적으로 가져와 quizInfo 배열에 저장합니다.

3. 문제 출력 : updateQuiz 함수는 quizInfo 배열을 순회하면서 각 퀴즈를 HTML 형태로 구성하여 동적으로 화면에 출력합니다.
퀴즈는 선택지가 랜덤으로 섞여서 표시됩니다.

4. 타이머 및 시작하기 : 사용자가 시작하기 버튼을 누르면 이름을 입력받고, 시간이 제한된 60분 동안 퀴즈를 풀게 됩니다.
타이머는 1초 간격으로 감소하며, 시간이 종료되면 알림이 표시됩니다.

5. 정답 확인 및 점수 계산 : 사용자가 모든 문제에 대한 답을 선택한 후 제출하기 버튼을 누르면, 정답을 확인하고 점수를 계산하여 알림으로 표시합니다.

6. 포기하기 및 다시 풀기 : 사용자가 포기하기 버튼을 누르면 정답과 해설을 표시하고, 다시 풀기 버튼을 통해 퀴즈를 처음부터 다시 풀 수 있습니다.

7. 이벤트 리스너 등록 : 페이지가 로드된 후에는 각종 버튼에 대한 클릭 이벤트 리스너가 등록되어 사용자의 상호작용을 처리합니다.

 <script>
        // 선택자
        const cbtWrap = document.querySelector(".cbt__wrap") 
        const cbtBox = document.querySelector(".cbt__box");
        const cbtSelect1 = document.getElementById("cbtSelect1");   
        const cbtSelect2 = document.getElementById("cbtSelect2");
        const cbtSelectTitle = document.querySelector(".cbt__select__title");
        const cbtBoxStart = document.querySelector(".cbt__box__start");
        const cbtSelectInput = document.querySelector(".cbt__select__input");
        const cbtTime = document.querySelector(".cbt__time span");
        const cbtQuiz = document.querySelector(".cbt__quiz");
        const cbtTitle = document.querySelector('.cbt__title');
        const cbtName = document.querySelector('.cbt__name');
        const cbtOmr = document.querySelector(".cbt__omr");
        const cbtSubmit = document.querySelector(".cbt__submit");
        const cbtGiveup = document.querySelector(".cbt__giveup");
        const cbtAgain = document.querySelector(".cbt__again");


        // 문제 정보
        let quizInfo = [];          // 모든 퀴즈 정보

        let quizScore = 0;          //퀴즈 점수
        let quizCorrect = 0;        // 퀴즈 맞은 갯수
        let remainingTime = 3600;     // 남은시간
        let timerInterval = "";

        // 문제 정보
        const hendleSelectChange = (e) => {
            let selectValue = e.target.value;
            let selectText = e.target.options[e.target.selectedIndex].text;

            cbtSelectTitle.innerHTML = selectText;
            cbtTitle.innerHTML=selectText +  "기출문제";
            fetchQuiz(selectValue, selectText);
        }


        // 문제 가져오기 
        const fetchQuiz = (value, text) => {
            fetch(`https://webstoryboy.github.io/webs2024/json/${value}.json`)
            .then(res => res.json())
            .then(items => {
                console.log(items);
                quizInfo = items.map((item, index) => {
                    const formattedQuiz = {
                        infoNum : index + 1,
                        infoQuestion : item.question,
                        infoDesc : item.desc,
                        infoAnswer : item.correct_answer
                    }
                    // 보기 가져오기
                    const choices = [...item.incorrect_answers, item.correct_answer]
                    // 보기 랜덤 섞기
                    for (let i=choices.length-1; i>0; i--){
                        const j = Math.floor(Math.random() * (i+1));
                        [choices[i], choices[j] ] = [choices[j], choices[i]] ;
                    }
                    formattedQuiz.infoChoices = choices;

                    // 문제에 대한 이미지가 있다면
                    if(item.hasOwnProperty("question_img")){
                        const src = "<img src='https://webstoryboy.github.io/webs2024/json/img/"
                        formattedQuiz.infoQuestionImg = src + item.question_img + ".jpg' alt ='정보처리기사'/>";
                    }

                    // 문제에 대한 보조 설명이 있다면
                    if(item.hasOwnProperty("question_desc")){
                        formattedQuiz.infoQuestionImg = item.question_desc;
                    }


                    return formattedQuiz;
                });
                console.log(quizInfo)
                updateQuiz();
            });
        }

        // 문제 출력하기
        const updateQuiz= ()=> {
            const exam = [];
            const omr = [];

            quizInfo.forEach((question, number) => {
                exam.push(`
                    <div class="cbt">
                        <div class="cbt__question">${question.infoNum}. ${question.infoQuestion}</div>
                        ${question.infoQuestionDesc ? `<div class="cbt__question__desc">${question.infoQuestionDesc}</div>` : '' }
                        ${question.infoQuestionImg ? ` <div class="cbt__question__img">${question.infoQuestionImg}</div>` : '' }
                        <div class="cbt__choices">
                            <input type="radio" id="select${number}_1" name="select${number}" value="${number}_1" onclick="answerSelect(this)">
                            <label for="select${number}_1"><span>${question.infoChoices[0]}</span></label>
                            <input type="radio" id="select${number}_2" name="select${number}" value="${number}_2" onclick="answerSelect(this)">
                            <label for="select${number}_2"><span>${question.infoChoices[1]}</span></label>
                            <input type="radio" id="select${number}_3" name="select${number}" value="${number}_3" onclick="answerSelect(this)">
                            <label for="select${number}_3"><span>${question.infoChoices[2]}</span></label>
                            <input type="radio" id="select${number}_4" name="select${number}" value="${number}_4" onclick="answerSelect(this)">
                            <label for="select${number}_4"><span>${question.infoChoices[3]}</span></label>
                        </div>
                        <div class="cbt__answer none">${question.infoAnswer}</div>
                        <div class="cbt__desc none">${question.infoDesc}</div>
                    </div>
                `);
                
                omr.push(`
                    <div class="omr">
                        <strong>${question.infoNum}</strong>
                        <input type="radio" name="omr${number}" id="omr${number}_1" value="${number}_1" onclick="answerSelect2(this)">
                        <label for="omr${number}_1"><span class="label-inner">1</span></label>
                        <input type="radio" name="omr${number}" id="omr${number}_2" value="${number}_2" onclick="answerSelect2(this)">
                        <label for="omr${number}_2"><span class="label-inner">2</span></label>
                        <input type="radio" name="omr${number}" id="omr${number}_3" value="${number}_3" onclick="answerSelect2(this)">
                        <label for="omr${number}_3"><span class="label-inner">3</span></label>
                        <input type="radio" name="omr${number}" id="omr${number}_4" value="${number}_4" onclick="answerSelect2(this)">
                        <label for="omr${number}_4"><span class="label-inner">4</span></label>
                    </div>
                `);
            })

            cbtQuiz.innerHTML = exam.join('');
            cbtOmr.innerHTML = omr.join('');
        }
        // 시간표시
        const displayTime = () => {
            const minutes = Math.floor(remainingTime / 60);
            const seconds = remainingTime % 60;
            const formattedSeconds = seconds < 10 ? `0${seconds}` : seconds;

            cbtTime.textContent =`${minutes}${formattedSeconds}초`;
        }
        // 타이머 작동
        const startTimer =() => {
            timerInterval = setInterval(() => {
                if(remainingTime > 0){
                    remainingTime--;

                    // 시간 표시
                    displayTime();
                   
                }else {
                    clearInterval(timerInterval);          // 시간이 다 되면 타이머 중지
                    alert("시간이 종료되었습니다.");
                }
            }, 1000);
        }

        // 정답 체크 표시
        const answerSelect = (el) => {
            const value = el.value.split('_');          // ['0', '2']
            const questionNum = parseInt(value[0]);     // 0
            const choiceNum = parseInt(value[1]);       // 2

            const selectedChoice = document.querySelector(`#select${questionNum}_${choiceNum}`);

            if(selectedChoice.checked){
                const omrChoice = document.querySelector(`#omr${questionNum}_${choiceNum}`);
                omrChoice.checked = true;
            }
        }
        
        // OMR 체크 표시
        const answerSelect2 = (el) => {  
            const value = el.value.split('_');          // ['0', '2']
            const questionNum = parseInt(value[0]);     // 0
            const choiceNum = parseInt(value[1]);       // 2
            
            const omrChoice = document.querySelector(`#omr${questionNum}_${choiceNum}`);

            if(omrChoice.checked){
                const selectChoice = document.querySelector(`#select${questionNum}_${choiceNum}`);
                selectChoice.checked = true;
            }
            
        }
       
        // 정답 체크
        const checkAnswers = () => {
            quizInfo.forEach((question, number) => {
                const choices = question.infoChoices;               // 정답지의 보기
                const userChoice = getSelectChoice(number);         // 사용자가 체크한 정답
                const cbtQuestion = document.querySelector(`.cbt:nth-child(${number + 1})`);
                const cbtDesc = cbtQuestion.querySelector('.cbt__desc');
                const cbtAnswer = cbtQuestion.querySelector(".cbt__answer");

                if(userChoice !== -1){
                    const selectedChoice = choices[userChoice -1]; 

                    if(selectedChoice === question.infoAnswer){
                        quizScore++;
                        quizCorrect++;
                        cbtQuestion.classList.add('good');
                    } else {
                        cbtQuestion.classList.add('bad');
                        cbtDesc.classList.remove('none');
                        cbtAnswer.classList.remove('none');
                    }
                }
                
            });

            quizScore = ( quizCorrect/quizInfo.length) *100; 
            alert(`전체 ${quizInfo.length} 문제 중에 ${quizCorrect}개를 맞추었습니다. 당신의 점수는 ${quizScore.toFixed(2)} 입니다.`)
        }

        // 선택된 보기의 인덱스 가져오기
        const getSelectChoice = (questionNumber) => {
            const choices = document.querySelectorAll(`input[name="select${questionNumber}"]:checked`);

            if(choices.length === 0){
                return -1;      // 체크하지 않은 문제는 -1을 반환
                alert("풀지 않은 문제가 있습니다. 다시 한번 확인해주세요!!");
            } else {
                return parseInt(choices[0].value.split('_')[1]);
            }
        }


        // 페이지가 로드된 후 실행
        document.addEventListener("DOMContentLoaded", () => {
            fetchQuiz("gineungsaJC2005_02", "정보처리기능사 2005년 2회");

            // 문제 선택
            cbtSelect1.addEventListener("change", hendleSelectChange);
            cbtSelect2.addEventListener("change", hendleSelectChange);

            // 시작하기 버튼
            cbtBoxStart.addEventListener("click", () => {
                // 이름이 입력되었는지 확인
                const playerName = cbtSelectInput.value.trim();

                if(playerName === ""){
                    alert("이름을 입력해야 시작할 수 있습니다.");
                } else {
                    alert("제한 시간은 60분이며, 확인을 누르면 바로 시작합니다.");
                    cbtBox.classList.add("none");
                    cbtWrap.classList.remove("none");
                    cbtName.innerHTML = playerName;
                    startTimer();
                }
            });

            // 정답 제출하기 버튼 클릭
            cbtSubmit.addEventListener("click", () => {
                // checkAnswers();

                // 모든 문제에 대한 체크 여부를 확인
                const allQuestionChecked = quizInfo.every((_, number) => {
                    return getSelectChoice(number) !== -1;
                });

                if(allQuestionChecked){
                    checkAnswers();

                    cbtGiveup.classList.add("none");
                    cbtSubmit.classList.add("none");
                    cbtAgain.classList.remove("none");

                    clearInterval(timerInterval);
                } else {
                    alert("모든 문제 대한 답을 선택해야 합니다. 체크 되지 않은 문제가 있습니다. 정답과 해설을 보고 싶으면 포기하기 누르세요")  
                }
            });

            // 포기하기 버튼
            cbtGiveup.addEventListener("click", () => {
                alert("정말 포기하겠습니까? 포기를 하면 정답과 해설을 볼 수 있습니다.");

                // 각 문제에 대한 정답과 해설을 표시
                quizInfo.forEach((question, number) => {
                    const cbtQuestion = document.querySelector(`.cbt:nth-child(${number + 1})`);
                    const cbtDesc = cbtQuestion.querySelector('.cbt__desc');
                    const cbtAnswer = cbtQuestion.querySelector('.cbt__answer');

                    cbtQuestion.classList.add("bad");
                    cbtDesc.classList.remove("none");
                    cbtAnswer.classList.remove("none");


                    
                });

                // 포기하기 버튼 숨김
                cbtGiveup.classList.add("none");
                cbtSubmit.classList.add("none");
                cbtAgain.classList.remove("none");

                //시간 정지
                clearInterval(timerInterval);
            });

            // 다시 풀기 버튼
            cbtAgain.addEventListener("click", () => {
                cbtBox.classList.remove("none");
                cbtWrap.classList.add("none");

                //모든 정답과 해설 숨기기
                quizInfo.forEach((question, number) => {
                    const cbtQuestion = document.querySelector(`.cbt:nth-child(${number + 1})`);
                    const cbtDesc = cbtQuestion.querySelector('.cbt__desc');
                    const cbtAnswer = cbtQuestion.querySelector('.cbt__answer');

                    cbtQuestion.classList.remove("good","bad");
                    cbtDesc.classList.add("none");
                    cbtAnswer.classList.add("none");

                   
                });
                // 모든 선택된 보기 초기화
                const selectedChoice =  document.querySelectorAll('input[type="radio"]:checked');
                selectedChoice.forEach(choice => {
                    choice.checked = false;
                });

                // 타이머 리셋
                remainingTime = 3600;
                displayTime();
                clearInterval(timerInterval);

                // 점수와 정답 개수 초기화
                quizScore = 0;
                quizCorrect = 0;

                // 버튼 활성화
                cbtGiveup.classList.remove("none");
                cbtSubmit.classList.remove("none");
                cbtAgain.classList.add("none");
            });

        });
    </script>