JAVASCRIPT

퀴즈 이펙트 객관식 여러문제 확인하기 슬라이드 유형

이미사용 2023. 3. 27. 23:37
명언
-
728x90
반응형

여러 문제를 한번에 보지 않고 다음 문제를 누르면 또 다른 문제가 나오게 하는 방법입니다. 

 

<!DOCTYPE html>
<html lang="ko">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>퀴즈 이펙트06</title>

    <link rel="stylesheet" href="css/reset.css">
    <link rel="stylesheet" href="css/quiz.css">
</head>
<body >
    <header id="header">
        <h1><a href="../javascript14.html">Quiz</a> <em>객관식 여러 문제 확인하기 슬라이드 유형</em></h1>
        <ul>
            <li><a href="quizeffect01.html">1</a></li>
            <li><a href="quizeffect02.html">2</a></li>
            <li><a href="quizeffect03.html">3</a></li>
            <li><a href="quizeffect04.html">4</a></li>
            <li><a href="quizeffect05.html">5</a></li>
            <li class="active"><a href="quizeffect06.html">6</a></li>
        </ul>
    </header>
    <!-- //header -->

    <main id="main">
        <div class="quiz__wrap">
            <div class="quiz">
                <div class="quiz__header">
                    <h2 class="quiz__title"></h2>
                </div>
                <div class="quiz__main">
                    <div class="quiz__question"></div>
                    <div class="quiz__view">
                        <div class="dog__wrap">
                            <div class="all"></div>
                            <div class="all2">맞힌갯수<span>?</span></div>
                            <div class="true">정답입니다!</div>
                            <div class="false">틀렸습니다!</div>
                            <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__choice">
                        <!-- <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">
                        <button class="next">다음 문제</button>
                    </div>
                    <div class="quiz__desc"></div>
                </div>
            </div>
            <div class="quiz__check">점수 확인하기</div>
            
        </div>
    </main>
    <!-- //main -->

    <footer id="footer">
        <a href="mailto:ghkddn132@naver.com">ghkddn132@naver.com</a>
    </footer>
    <!-- //footer -->
    <script>
        //문제 정보
        const quizInfo = [
            {
                infoType: "정보처리 기능사",
                infoTime: "2008년 1회",
                infoNumber: "20080101",
                infoQuestion: "101101<small>(2)</small>의 2의 보수는 얼마인가?",
                infoChoice: ["110111<small>(2)</small>","110001<small>(2)</small>","111000<small>(2)</small>","010011<small>(2)</small>"],
                infoAnswer: "010011(2)",
                infoDesc: "2의 보수로 바로 바꾸는 방법은 오른쪽 끝에서부터 처음 1을만날때까지는 똑같이 적고 나머지는 1의보수 바꾸는 방식대로 0은 1로 1은 0으로 바꾸어 주면 됩니다."
            },{
                infoType: "정보처리 기능사",
                infoTime: "2008년 1회",
                infoNumber: "20080102",
                infoQuestion: "불 대수의 정리 중 옳지 않은 것은?",
                infoChoice: ["A + A = 1","A· A = A","1 + A = 1","A· 1 = A"],
                infoAnswer: "A + A = 1",
                infoDesc: "A + A = A 입니다."
            },{
                infoType: "정보처리 기능사",
                infoTime: "2008년 1회",
                infoNumber: "20080103",
                infoQuestion: "명령어 구성에서 연산자의 기능에 해당하지 않는 것은?",
                infoChoice: ["입· 출력기능","주소지정기능","제어기능","함수연산기능"],
                infoAnswer: "주소지정기능",
                infoDesc: "명령어 = 명령어 코드부 + 명령어 주소부 Instruction = Op_Code + Operand 연산자란 명령어 코드부를 이야기 하므로 주소지정 기능은 없 습니다. 주소지정 기능은 명령어 주소부에 해당 합니다.",
            },{
                infoType: "정보처리 기능사",
                infoTime: "2008년 1회",
                infoNumber: "20080104",
                infoQuestion: "다음 중 플립플롭의 종류가 아닌 것은",
                infoChoice: ["R-S","J-K","D","R"],
                infoAnswer: "R",
                infoDesc: "R 플립플롭은 없습니다. 플립플롭에는 RS,D,JK,T 가 있습니다"
            },{
                infoType: "정보처리 기능사",
                infoTime: "2008년 1회",
                infoNumber: "20080105",
                infoQuestion: "클록펄스(Clock Pulse)에 의해서 기억 내용을 한자리씩 이동하는 레지스터는?",
                infoChoice: ["시프트 레지스터","누산기 레지스터","B 레지스터","D 레지스터"],
                infoAnswer: "시프트 레지스터",
                infoDesc: "한자리씩 이동하는 레지스터는 시프트 레지스터 입니다."
            },{
                infoType: "정보처리 기능사",
                infoTime: "2008년 1회",
                infoNumber: "20080106",
                infoQuestion: "입/출력 장치와 주기억 장치 사이에 위치하여 데이터 처리속도의 차이를 줄이는데 도움이 되는 장치는?",
                infoChoice: ["입/출력 채널","명령 해독기","연산장치","인덱스 레지스터"],
                infoAnswer: "입/출력 채널",
                infoDesc: "채 중 입 : 채널은 중앙처리장치(주기억장치)와 입출력 장치사이에 존재 합니다."
            }
        ];
</body>
</html>

 

우선 선택자를 만들어  "quizInfo" 에 있는 정보를 넣어 줄수 있도록 합니다.

그리고 다음문제로 넘어 가는 버튼과 설명을 숨겨 주었습니다.

        // 선택자
        const quizWrap = document.querySelector (".quiz__wrap");
        const quizTitle = quizWrap.querySelector (".quiz__title");
        const quizChoice = quizWrap.querySelector (".quiz__choice");
        const quizQuestion = quizWrap.querySelector (".quiz__question");
        const dogWrap = quizWrap.querySelector(".dog__wrap");
        const countall = quizWrap.querySelector(".dog__wrap .all");
        const quizNext = quizWrap.querySelector(".quiz__answer .next");
        const quizAnswer = quizWrap.querySelector(".quiz__answer");
        const quizDesc = quizWrap.querySelector(".quiz__desc");

        let quizCount = 0;
        let quizScore = 0;

        const updateQuiz1 = (index) => {
            let typeTag =`
                <span>${quizInfo[index].infoType}</span>
                <em>${quizInfo[index].infoTime}</em>
            `;
            let questionTag =`
                <em>${index+1}</em>.
                <span>${quizInfo[index].infoQuestion}</span>
            `;
            let countallTag = `
                총 문제: ${index+1}/${quizInfo.length}<br>
            `;
            let choiceTag = `
                <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>
            `;
            let descTag = `
                정답은 ${quizInfo[index].infoAnswer}입니다.<br>
                ${quizInfo[index].infoDesc}
            `;

            quizTitle.innerHTML = typeTag;
            quizQuestion.innerHTML = questionTag;
            quizChoice.innerHTML = choiceTag;
            quizDesc.innerHTML = descTag;
            countall.innerHTML = countallTag;
            
            //보기 선택자
            const quizChoiceSpan = quizWrap.querySelectorAll(".quiz__choice span");
            const quizChoiceInput = quizWrap.querySelectorAll(".quiz__choice input");
            
            // quizChoiceSapn.forEach((span, num) => {
            //     span.setAttribute("onclick", "choiceSelected(this)");
            // });
            for(let i=0; i<quizChoiceSpan.length; i++){
                quizChoiceSpan[i].setAttribute("onclick","choiceSelected(this)");
                // quizChoiceInput.disabled = "true";
            };

            //다음 버튼 숨기기
            quizAnswer.style.display = "none"
            quizDesc.style.display = "none"

        };
        updateQuiz1(quizCount);

//보기 선택자 에서는 변수 두개를 만들어 querySelectorAll을 해주시고 input 부분과 span부분으로 나눠 줍니다.

그후 span을 넣은 quizChoiceSpan변수로 forEach문을 만들어  setAttribute()를 사용하여span이 있는곳에  onclick을  했을때 span에 있는 값을 가져 오고 그것을 choiceSelected(this)에 넣어줍니다.

        function choiceSelected(answer){
            let userAnswer = answer.textContent;               //사용자 정답
            let currentAnswer = quizInfo[quizCount].infoAnswer //문제 정답

            if(userAnswer == currentAnswer){
                quizScore++
                console.log("정답입니다.");
                dogWrap.classList.add("like");     
            } else {
                console.log("오답입니다.");
                dogWrap.classList.add("dislike");
            }

            document.querySelector(".dog__wrap span").innerHTML = quizScore; //맞힌 갯수 확인

            //다음 버튼, 해설 나타나기
            quizAnswer.style.display = "block"
            quizDesc.style.display = "block"
            
        };

그러고  choiceSelected(this)를  choiceSelected(answer)로 바꾸어 유저가 입력한 답 answer와 실제 답과 비교하여 같을때

quizScore를 1더해주고 dogwrap에 like를 넣어 줍니다. 아닐경우 dislike를 넣어 줍니다. 그리고 밑에 맞힌 갯수quizScore를 dog__wrap span을 통해 넣어 주도록 하고 다음 나오는 버튼과 해설이 나타 내도록 하였습니다.

        //정답 확인
        quizNext.addEventListener("click", () => {
            if(quizScore == quizInfo.length-1){
                document.querySelector(".quiz__check").textContent = Math.ceil((quizScore / quizInfo.length) * 100) + "점";
            } else {
                quizCount++;    //quizCount에 1을더해서
                updateQuiz1(quizCount);     //updateQuiz()를 변경
                
                dogWrap.classList.remove("like", "dislike");  //강아지 초기화
            }
        });

정답을 확인하고 다음문제로 넘어가는 방법은 quizNext를 이용해 click을 했을때 조건으로  quizScore와 배열의 순서합 -1 이랑 같을떄 조건을 true를실행하고 아니면 quizCount를 1더해주고 updataQuiz1(quizCount)로 다음문제를 불러오면서 강아지의 움직임을 없애주고 강아지의 모션을 없애주기 위해 remove를 이용하여 like나 dislike를 없어지도록 하였습니다.

 

 

정리

setAttribute()  JavaScript에서 사용되는 메소드로, 지정된 HTML 요소의 속성(attribute) 값을 설정하는 데 사용됩니다.
onclick 클릭 이벤트가 발생했을 때 실행할 JavaScript 코드를 지정하는 데 사용됩니다.