JAVASCRIPT

퀴즈 이펙트 CBT 확인 유형 (보충)

이미사용 2023. 4. 4. 22:43
명언
-
728x90
반응형

퀴즈 이펙트 CBT확인 유형을 보충 하였습니다.

<script>
        const cbtQuiz = document.querySelector(".cbt__quiz");
        const cbtomr = document.querySelector(".cbt__omr");
        const cbtSubmit = document.querySelector(".cbt__submit");
        const cbtLength = document.querySelector(".cbt_length");
        const cbtRest = document.querySelector(".cbt__rest");
        const cbtstart = document.querySelector(".cbt__start");

        let questionAll = [];              //모든 퀴즈 정보
        let questionLength = 0;            //전체 문제수
        let questionRest = questionLength; //남은 문제수

        document.querySelector(".start").addEventListener("click", () => {
            cbtstart.style.display = "none"
        });

전체 문제의 수와 남은 문제의 수를 가져오기 위해 우선 선택자를 추가 하였습니다.

그리고 문제가 바로 안보이게 하기 위해 블라인드 처리를 했는데 시작하기를 누르면 사라지게 만들었습니다.

        //데이터 가져오기
        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.question_desc = item.question_desc;
                        }

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

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


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

                    //전체 문제수 만들기
                    questionLength = questionAll.length;
                    cbtLength.innerHTML = questionLength;
                    cbtRest.innerHTML = questionLength;

                })  //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 style='width:300px' src="${question.question_img}" alt=""></div>
                        <div class="cbt__question__desc">${question.question_desc}</div>
                        <div class="cbt__selects">
                            <input type="radio" id="select${number}_1" name="select${number}" value="${number}_0" onclick="answerSelect2(this)">
                            <label for="select${number}_1"><span>${question.choice1}</span></label>
                            <input type="radio" id="select${number}_2" name="select${number}" value="${number}_1" onclick="answerSelect2(this)">
                            <label for="select${number}_2"><span>${question.choice2}</span></label>
                            <input type="radio" id="select${number}_3" name="select${number}" value="${number}_2" onclick="answerSelect2(this)">
                            <label for="select${number}_3"><span>${question.choice3}</span></label>
                            <input type="radio" id="select${number}_4" name="select${number}" value="${number}_3" onclick="answerSelect2(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" onclick="answerSelect(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}_1" onclick="answerSelect(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}_2" onclick="answerSelect(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}_3" onclick="answerSelect(this)">
                        <label for="omr${number}_4"><span class="label-inner">4</span></label>
                    </div>
                `)
            });

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

            document.querySelectorAll(".cbt__question__desc").forEach(el => {
                if(el.innerText == "undefined"){
                    el.style.display = "none";
                }
            });
        };

문제 만들기 안에 문제의 설명이 없으면 undefined가 뜨는데 그것을 없애주기 위해  display = "none"을 해주었습니다.

 

        //보기 체크
        const answerSelect2 = (elem) => {
            const answer = elem.value;             //클릭 했을때 vlaue값을 가져옴
            const answerNum = answer.split("_")    //

            const select = document.querySelectorAll(".cbt__omr .omr"); //전체 문항 수 100개를 가져온다
            const label = select[answerNum[0]].querySelectorAll("input"); //보기 4개
            label[answerNum[1]].checked = true;

            const answerInputs = document.querySelectorAll(".cbt__selects input:checked");
            cbtRest.innerHTML = questionLength - answerInputs.length;
        }
        //보기 체크2
        const answerSelect = (elem) => {
            const answer = elem.value;
            const answerNum = answer.split("_")    //

            const select = document.querySelectorAll(".cbt__quiz .cbt"); //전체 문항 수 100개를 가져온다
            const label = select[answerNum[0]].querySelectorAll("input"); //보기 4개
            label[answerNum[1]].checked = true;

            const answerInputs = document.querySelectorAll(".cbt__selects input:checked");
            cbtRest.innerHTML = questionLength - answerInputs.length;
        }
        
        cbtSubmit.addEventListener("click", answerQuiz);
        dataQuestion();
        </script>

문제에 있는 정답 체크 들과 omr에 있는 정답 체크 들을 연동 시키기 위해 사용자가 체크를 하게 되면 체크된 정답의 값을 onclick의 answerSelect2을 통해 value를 가져 왔습니다. 그리고 그 value값 사이에있는 "_"를  구분자로하여 split 안에있는 숫자를 배열로 나워 주었습니다.그후 omr에 있는 전체 문항수를 가져오고  label 이라는 변수를 만들어 체크 되었을때  문제 밑에 있는 정답 4개중 하나를누르면 omr에 정답도 같은 숫자로 체크가 되게 할 수 있습니다.

밑에도 마찬가지로 omr을 눌렀을때  문제 밑에 있는 정답과 같은 번호로 체크가 되게 만들어 주었습니다.

그 후 남은 문제를 구하기 위해  체크한 값을 가져와 그값과 전체 문제 수를 빼고 선택자에게 다시 넣어주면 체크 할때 마다 남은 문자 수가 감소하는 것을 볼수 있습니다.