공부하기

퀴즈 유형7 미션

Hyeon been 2023. 4. 5. 20:01

한번씩 읽고 가세요.

“ 지연되는 프로젝트에 인력을 더 투입하면 오히려 더 늦어진다. ”

- Frederick Philips Brooks
Mythical Man-Month 저자
728x90

 

미션 1 : 점수 결과 표시

cbtSubmit.addEventListener("click", answerQuiz)

제출하기 버튼을 눌렀을때 점수를 표시 해줘야하기 때문에  이벤트가 적용되어있는 answerQuiz에 

 document.querySelector(".cbt__result span").innerHTML = Math.ceil((quizScore /  questionAll.length) *100) + "점"

를 넣어주었다.

그리고 출력 될 cbt__result span 이라는  창을 만들어 hide를 주어 숨겨놓은 다음 클릭 하면 나올수 있게 

            const cbtResult = document.querySelector(".cbt__result ").classList.remove("hide")

코드를 주었다.

미션 2 : 시간  초  0 추가 하기

        const displayTime = () => {
            if (questionTimeRemain <= 0) {
                return "0분 00초";
            } else {
                let minutes = Math.floor(questionTimeRemain / 60);
                let seconds = questionTimeRemain % 60 < 10 ? "0" + (questionTimeRemain % 60) : questionTimeRemain % 60;
                
                return minutes + "분 " + seconds + "초";
                //초의 단위가 한자리 수가 되면 앞에 0을 붙여주기

            }
        }

초의 단위가 10보다 아래로 내려가면 09초가 아닌 9초가 나오기 때문에 조건문을 사용해 second가 10 보다 작을때 앞에 0을 붙여주는 코드를 넣었다.

미션 3 :  이름  > 입력

당신의 이름은 <input type="text" class="name"> 입니다.<br>

인풋 박스를 선택자로 만들고

<div class="cbt__title">수험자 : <em class="cbt__name">김현빈</em></div>

cbt__name 부분에 넣을거기 때문에 이 친구도 선택자를 만들어준 후

          cbtName.innerHTML = `${Name.value}`

input박스의 value 값을 cbt__name부분에 가져와 준다.

 시작 버튼을 누르면 적용하기 때문에

        const startQuiz = () => {
            cbtStart.classList.add("hide") //모달창 제거
            cbtName.innerHTML = `${Name.value}`

            //시간 설정
            questionTime = setInterval(reduceTime, 1000)
        }

startQuiz함수에 넣어 실해시켜줍니다.

 

스크립트 코드

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

        const cbtQuiz = document.querySelector(".cbt__quiz")
        const cbtOmr = document.querySelector(".cbt__omr")
        const cbtSubmit = document.querySelector(".cbt__submit")
        const cbtRest = document.querySelector(".cbt__rest")
        const cbtLength = document.querySelector(".cbt__length")
        const cbtBtn = document.querySelector(".minimal");
        const cbtStart = document.querySelector(".cbt__start");
        const cbtIndex = document.querySelector(".cbt__index");
        const cbtIndex2 = document.querySelector(".cbt__index2");
        const cbtViewSubject = document.querySelector(".cbt__view .subject");
        const cbtHeader = document.querySelector(".cbt__header h2");
        const cbtTime = document.querySelector(".cbt__time");
        const cbtName = document.querySelector(".cbt__name");
        const Name = document.querySelector(".name");





        let quizCount = 0;
        let quizScore = 0;
        let querySelectorAll = []; //모든퀴즈 정보
        let questionLength = 0;                //전체 문제수
        let questionRest = questionLength;     //남은 문제수
        let questionTime = "";
        let questionTimeRemain = "10"

        //시작하기
        const startQuiz = () => {
            cbtStart.classList.add("hide") //모달창 제거
            cbtName.innerHTML = `${Name.value}`

            //시간 설정
            questionTime = setInterval(reduceTime, 1000)
        }



        //클릭시 시작


        //데이터 불러오기
        const dataQuestion = (value) => {
            fetch(`https://kebab000.github.io/web2023/gineungsaJSON/${value}.json`)
                .then(res => res.json())          //.then() .then  () 체인 방식
                .then(items => {
                    questionAll = items.map((item, index) => {
                        const formattedQuestion = {
                            question: item.question,
                            number: index + 1,
                        }
                        const answerChoices = [...item.incorrect_answers]; //오답 불러오기
                        formattedQuestion.answer = Math.round(Math.random() * answerChoices.length) + 1; //정답을 핸덤으로 불러오기

                        answerChoices.splice(formattedQuestion.answer - 1, 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;
                        }

                        return formattedQuestion;
                    })

                    newQuestion();   //문제만들기

                    //전체 문제수
                    questionLength = questionAll.length;
                    cbtLength.innerHTML = questionLength
                    cbtRest.innerHTML = questionLength
                })
                .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="https://kebab000.github.io/web2023/gineungsaJPG/${question.question_img}.jpg" 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}_1" 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}_2" 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}_3" 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}_4" 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}_1" 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}_2" 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}_3" onclick="answerSelect(this)">
                        <label for="omr${number}_3">
                            <span class="label-inner">3</span>
                        </label>
                        <input type="radio" name="omr${number}" id=id="omr${number}_4" value="${number}_4" 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(desc => {
                if (desc.innerHTML === "undefined") {
                    desc.classList.add("hide")
                }
            })

            document.querySelectorAll(".cbt__question__img").forEach(img => {
                let src = img.querySelector("img").src;

                if (src.includes("undefined")) {
                    img.classList.add("hide")
                }

            })

            // const questionzDesc = document.querySelectorAll(".cbt__question_desc");

            // questionzDesc.forEach(e => {
            //     if(e.innerHTML == "undefined"){
            //         e.style.display = "none";
            //     }
            // });

        }


        //정답 확인
        const answerQuiz = () => {
            const cbtResult = document.querySelector(".cbt__result ").classList.remove("hide")
            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;



                if (numberAnswer == question.answer) {
                    console.log("정답입니다.");
                    cbtSelects[number].parentElement.classList.add("good");
                    quizScore++
                } else {
                    console.log("오답입니다.")
                    cbtSelects[number].parentElement.classList.add("bad");

                    //오답 일 경우 정답 표시
                    const label = cbtSelects[number].querySelectorAll("label");
                    label[question.answer - 1].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");
                }
                document.querySelector(".cbt__result span").innerHTML = Math.ceil((quizScore /  questionAll.length) *100) + "점"
            });

        }
        // 보기 체크
        const answerSelect2 = (elem) => {
            const answer = elem.value;
            const answerNum = answer.split("_");

            const select = document.querySelectorAll(".cbt__omr .omr");     //전체 문항 수 100개
            const label = select[answerNum[0]].querySelectorAll("input");   //보기 4개
            label[answerNum[1] - 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] - 1].checked = true;

            const answerInputs = document.querySelectorAll(".cbt__selects input:checked");
            cbtRest.innerHTML = questionLength - answerInputs.length;
        }

        // const changeSelect = () => {
        //     let selectedValue = cbtIndex.options[cbtIndex.selectedIndex].value;
        //     let selectText = cbtIndex.options[cbtIndex.selectedIndex].text;

        //     alert(selectText)
        // }
        // const changeSelect2 = () => {
        //     let selectedValue = cbtIndex2.options[cbtIndex2.selectedIndex].value;
        //     let selectText = cbtIndex2.options[cbtIndex2.selectedIndex].text;

        //     alert(selectText)
        // }

        //제목 선택

        const changeSelect = (e) => {
            let selectValue = e.value;
            let selectText = e.options[e.selectedIndex].text;

            console.log(selectValue)
            console.log(selectText)

            cbtViewSubject.innerHTML = selectText
            cbtHeader.innerHTML = selectText
            dataQuestion(selectValue)
        }

        //시간 설정
        const reduceTime = () => {
            questionTimeRemain--;
            console.log("first")

            if (questionTimeRemain == 0) endQuiz();

            cbtTime.innerText = displayTime();

        }

        //시간 표시
        const displayTime = () => {
            if (questionTimeRemain <= 0) {
                return "0분 00초";
            } else {
                let minutes = Math.floor(questionTimeRemain / 60);
                let seconds = questionTimeRemain % 60 < 10 ? "0" + (questionTimeRemain % 60) : questionTimeRemain % 60;
                
                return minutes + "분 " + seconds + "초";
                //초의 단위가 한자리 수가 되면 앞에 0을 붙여주기

            }
        }
        



        //시험 끝
        const endQuiz = () => {
            alert("시험끝")
        }

        cbtBtn.addEventListener("click", startQuiz);
        cbtSubmit.addEventListener("click", answerQuiz);
        dataQuestion();





        // 버블버튼
        const bubbleBtn = () => {

            // clips the value to given range
            const clip = (v, min, max = Infinity) => {
                if (v < min) return min;
                else if (v > max) return max;
                else return v;
            };

            // generated random value from given range
            const randRange = (min, max) => Math.random() * max + min;

            // create bubble on x and y position inside target with given hue theme
            function bubble(x, y, rect, hue, target) {
                // variables
                const size = randRange(20, rect.width / 5);
                const circleHue = hue + randRange(-20, 20);
                const animDuration = randRange(clip(size ** 2 / 1000, 1), 6)
                const zIndex = Math.random() < 0.1 ? 2 : -1;
                // 원 만들기
                const circle = document.createElement("span");
                circle.className = "lit";
                circle.style.left = x + "px";
                circle.style.top = y + "px";
                circle.style.width = size + "px";
                circle.style.height = size + "px";
                circle.style.background = `hsl(${circleHue}deg, 100%, 80%)`;
                circle.style.zIndex = zIndex
                circle.style.animationDuration = animDuration + "s";
                target.appendChild(circle);
            }

            document.querySelectorAll("[data-lit-hue]").forEach((target) => {
                const rect = target.getBoundingClientRect();
                const hue = Number(target.getAttribute("data-lit-hue"));
                const count = Number(target.getAttribute("data-lit-count") || 50);

                for (let i = 0; i < count; i++) {
                    const x = randRange(0, rect.width);
                    const y = randRange(0, rect.height);
                    bubble(x, y, rect, hue, target);
                }
            });
        }
        bubbleBtn();