JAVASCRIPT

퀴즈 이펙트 json을 이용한 CBT 확인 유형

이미사용 2023. 4. 3. 22:51
명언
-
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>퀴즈 이펙트07</title>

    <link rel="stylesheet" href="css/reset.css">
    <link rel="stylesheet" href="css/quiz.css">
    
    <!-- 파비콘 -->
    <link rel="shortcut icon" type="image/x-icon" href="img/favicon.png">
    <link rel="apple-touch-icon" sizes="114x114" href="img/favicon.png">
    <link rel="apple-touch-icon" href="img/favicon.png">

</head>
<body >
    <header id="header">
        <h1><a href="../javascript14.html">Quiz</a> <em>객관식 확인 CBT 유형</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><a href="quizeffect06.html">6</a></li>
            <li class="active"><a href="quizeffect07.html">7</a></li>
        </ul>
    </header>
    <!-- //header -->

    <main id="main">
        <div class="quiz__wrap__cbt">
            <div class="cbt__header">
                <h2>2020년 1회 정보처리기능사 기출문제</h2>
            </div>
            <div class="cbt__conts">
                <div class="cbt__quiz">
                    <!-- <div class="cbt">
                        <div class="cbt__question"><span>1 </span>.객체지향 프로그램에서 데이터를 추상화하는 단위는?</div>
                        <div class="cbt__question__img"><img src="img/gineungsaJC2023_01_01.jpg" alt="기능사"></div>
                        <div class="cbt__selects">
                            <input type="radio" id="select1">
                            <label for="select1"><span>클래스</span></label>
                            <input type="radio" id="select2">
                            <label for="select2"><span>메소드</span></label>
                            <input type="radio" id="select3">
                            <label for="select3"><span>상속</span></label>
                            <input type="radio" id="select4">
                            <label for="select4"><span>메시지</span></label>
                        </div>
                        <div class="cbt__desc">객체지향언어는 이다.</div>
                        <div class="cbt__answer"></div>
                    </div> -->
                </div>
            </div>
            <div class="cbt__aside">
                <div>
                    <div class="cbt__time">남은 시간 59분 10초</div>
                    <div class="cbt__submit">답안지 제출하기</div>
                </div>
                <div class="cbt__info">
                    <div>
                        <div class="cbt__title">수험자 : <em></em></div>
                        <div class="cbt__score">
                            <span>전체 문제수 : <em class="allcount">1</em>문항<br></span>
                            <span>남은 문제수 : <em class="count">1</em>문항</span>
                        </div>
                    </div>
                    <div class="cbt__omr">
                        <!-- <div class="omr">
                            <strong>1</strong>
                            <input type="radio" id="omr0_1">
                            <label for="omr0_1">
                                <span class="label-inner">1</span>
                            </label>
                            <input type="radio" id="omr0_2">
                            <label for="omr0_2">
                                <span class="label-inner">2</span>
                            </label>
                            <input type="radio" id="omr0_3">
                            <label for="omr0_3">
                                <span class="label-inner">3</span>
                            </label>
                            <input type="radio" id="omr0_4">
                            <label for="omr0_4">
                                <span class="label-inner">4</span>
                            </label>
                        </div> -->
                    </div>
                </div>
            </div>
        </div>
    </main>
    <!-- //main -->

    <!-- <footer id="footer">
        <a href="mailto:ghkddn132@naver.com">ghkddn132@naver.com</a>
    </footer> -->
    <!-- //footer -->

class의 cbt 부분과 omr 부분을 주석처리 하고 script 부분에서 반복하여 나오게 하였습니다.

<script>
        const cbtQuiz = document.querySelector(".cbt__quiz");
        const cbtomr = document.querySelector(".cbt__omr");
        const cbtSubmit = document.querySelector(".cbt__submit");
        const quizallcount = document.querySelector(".cbt__score .allcount")
        const quizcount = document.querySelector(".cbt__score .count")

        let questionAll = []; //모든 퀴즈 정보

        //데이터 불러오기
        const dataQuestion = () => {
            fetch("json/gisa2020_01.json") //json을가져옴
            .then(res => res.json())  //fetch에서 가져온것을 res.json로 변경 하여 가져온후 실행
            .then(items => {        //가져온 json을 items로 변경

                // console.log(items)
                questionAll = items.map((item, index) => {
                    const formattedQuestion = {
                        question: item.question,
                        number: index + 1,
                    }
                    const answerChoices = [...item.incorrect_answers]; //오답 불러오기
                    formattedQuestion.answer = Math.trunc(Math.random() * (answerChoices.length+1)); //정답을 랜덤으로 불러오기
                    // console.log(formattedQuestion.answer)
                    answerChoices.splice(formattedQuestion.answer, 0, item.correct_answer); //정답을 랜덤으로 추가


                    //보기를 추가
                    answerChoices.forEach((choice, index) => {  
                        formattedQuestion["choice"+ (index+1)] = choice;
                    });

                    //문제에 대한 해설이 있으면 출력
                    if(item.hasOwnProperty("question_desc")){
                        formattedQuestion.QuestionDesc = item.question_desc;
                    }

                    //문제에 대한 이미지가 있으면 출력
                    if(item.hasOwnProperty("question_img")){
                        formattedQuestion.QuestionImg = item.question_img;
                    }

                    //해설이 있으면 출력
                    if(item.hasOwnProperty("desc")){
                        formattedQuestion.desc = item.desc;
                    }

                    
                    // console.log(formattedQuestion);
                    return formattedQuestion;
                });
                newQuestion(); //문제 만들기

            })  //res.json을 items으로 하여 상수
            .catch((err) => console.log(err));
        }

        //문제 만들기
        const newQuestion = () => {
            const exam = [];
            const omr = [];

            questionAll.forEach((question, number) => {
                exam.push(`
                    <div class="cbt">
                        <div class="cbt__question"><span>${question.number} </span>. ${question.question}</div>
                        <div class="cbt__question__img"><img src="img/gineungsaJC2023_01_01.jpg" alt="기능사"></div>
                        <div class="cbt__selects">
                            <input type="radio" id="select${number}_1" name="select${number}" value="${number+1}_0" onclick="answerSelect(this)">
                            <label for="select${number}_1"><span>${question.choice1}</span></label>
                            <input type="radio" id="select${number}_2" name="select${number}" value="${number+1}_1" onclick="answerSelect(this)">
                            <label for="select${number}_2"><span>${question.choice2}</span></label>
                            <input type="radio" id="select${number}_3" name="select${number}" value="${number+1}_2" onclick="answerSelect(this)">
                            <label for="select${number}_3"><span>${question.choice3}</span></label>
                            <input type="radio" id="select${number}_4" name="select${number}" value="${number+1}_3" onclick="answerSelect(this)">
                            <label for="select${number}_4"><span>${question.choice4}</span></label>
                        </div>
                        <div class="cbt__desc hide">${question.desc}</div>
                    </div>
                `)
                
                omr.push(`
                    <div class="omr">
                        <strong>${question.number}</strong>
                        <input type="radio" name="omr${number}" id="omr${number}_1" value="${number}_0">
                        <label for="omr${number}_1"><span class="label-inner">1</span></label>
                        <input type="radio" name="omr${number}" id="omr${number}_2" value="${number}_1">
                        <label for="omr${number}_2"><span class="label-inner">2</span></label>
                        <input type="radio" name="omr${number}" id="omr${number}_3" value="${number}_2">
                        <label for="omr${number}_3"><span class="label-inner">3</span></label>
                        <input type="radio" name="omr${number}" id="omr${number}_4" value="${number}_3">
                        <label for="omr${number}_4"><span class="label-inner">4</span></label>
                    </div>
                `)
            });

            cbtQuiz.innerHTML = exam.join('');
            cbtomr.innerHTML = omr.join('');

            quizallcount.innerText = questionAll.length;
        };
        
        // 정답 확인
        const answerQuiz = () => {
            const cbtSelects = document.querySelectorAll(".cbt__selects");

            questionAll.forEach((question, number) => {
                const quizSelectsWrap = cbtSelects[number];
                const userSelector = `input[name=select${number}]:checked`;
                const userAnswer = (quizSelectsWrap.querySelector(userSelector) || {}).value;
                const numberAnswer = userAnswer ? userAnswer.slice(-1) : undefined;
                // console.log(numberAnswer)
                
                if(numberAnswer == question.answer){
                    console.log("정답");
                    cbtSelects[number].parentElement.classList.add("good");
                } else {
                    console.log("오답");
                    cbtSelects[number].parentElement.classList.add("bad");
                    
                    const label = cbtSelects[number].querySelectorAll("label");
                    label[question.answer].classList.add("correct")
                    
                }
                const quizDesc = document.querySelectorAll(".cbt__desc");
                
                if(quizDesc[number].innerText == "undefined"){
                    quizDesc[number]. classList.add("hide");
                } else quizDesc[number]. classList.remove("hide");
            });
        }
        const answerSelect = () => {
            
        }

        cbtSubmit.addEventListener("click", answerQuiz);
        dataQuestion();
    </script>
</body>
</html>

·json에 있는 데이터를 불러와서 itmes로 저장해준후 map으로 json파일에있는 데이터를 하나씩 빼와 questionAll에 저장 해주었습니다.

·newQuestion의 익명함수를 만듣후 빈배열이 있는 변수 두개를 만들고 그안에 forEach를 이용해 questionAll에있는 문제의 내용을 가져와 각배열 안에 넣어주면 문제가 여러게 나오게 됩니다.

·정답을 확인하기 위해 우선 사용자의 체크한 답을 가져오기위해 cbtSelects를 가져오고 그안에 서 사용자가 체크 한값이 있거나 없을 경우 value 값을 가져옵니다 그vlaue값을 뒤에서 부터 1칸 앞으로간 후에 그부분 만 가져와서 진짜 답과 사용자의 선택한 답을 비교합니다. 그 후 정답이면 cbtSelects의 부모에게 classlist로 하여 good을 넣어 주면 맞춤 표시가 나옵니다. 틀렸을때  설명과 정답이 있는곳에 빨간색으로 바뀌게 됩니다. 그후 조건은 quizDesc[number]에게 "undefined"가 있으면 hide를 붙여 없애주고 있으면 hide를 지우고 quizDesc[number]를 보여주게합니다. 제출하기를 눌렀을때 "click" anwerQuiz 함수가 실행되게 하였습니다. 

JSON 데이터를 저장하고 교환하기 위한 경량의 데이터 형식입니다. JSON은 인간이 읽고 쓰기 쉽고, 기계가 분석하고 생성하기 쉽습니다
Map key-value 쌍으로 이루어진 자료구조로, 각각의 key와 그에 대응하는 value로 이루어져 있습니다. Map은 자바스크립트에서 제공되는 객체입니다.
Math.trunc  주어진 숫자의 소수 부분을 제외한 정수 부분을 반환하는 자바스크립트 내장 함수입니다.
splice 배열의 내용을 추가하거나 삭제할 때 사용하는 자바스크립트의 배열 메서드 중 하나입니다. splice 메서드는 기존 배열의 요소를 삭제하거나 새로운 요소를 추가하는데 사용됩니다.
slice 배열의 일부분을 추출하여 새로운 배열을 반환하는 자바스크립트 내장 함수입니다.