필요없는 목록/CSS 스타일

(부족)CBT 퀴즈 따라 만들기

비밀안 2023. 4. 3. 20:55
클릭

버튼을 클릭하면 명언이 나와요

-

이름이 나와요

최종 완성본 

오늘은 CBT퀴즈 만들기를 따라 만들었습니다.

초반에는 이해가 갔다가 마지막에 너무 헷갈렸습니다.

HTML코드

<body>
    <header id="header">
        <h1>
            <a href="../assets/javascript/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>
    <!-- testAnGyonam -->
    <!-- //header -->


    <!-- 
        문제 정보
        (면제) 정보처리기능사 10년 7월 11일 4회 [기능사 면제]
        (해야해) 웹디자인기능사 필기 기출문제 및 CBT 2011년 02월 13일(1회) 정리(60번까지) 
    -->
    <main id="main">
        <div class="container">

            <div class="quiz__wrap__cbt">
               <!-- 답안지 -->
               <div class="cbt__header">
                   <h2>2011년 1회 웹디자인기능사 기출문제</h2>
                   <div class="cbt__ts">
                       <div class="cbt__time">
                           <!-- <svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" class="w-6 h-6">
                               <path stroke-linecap="round" stroke-linejoin="round" d="M12 6v6h4.5m4.5 0a9 9 0 11-18 0 9 9 0 0118 0z" />
                           </svg>             -->
                           남은 시간 59분 10초
                       </div>
                       <div class="cbt__sumit">답안지 제출하기</div>
                   </div>
               </div>
               <div class="cbt__conts">
                  <div class="container">

                      <div class="cbt__quiz">
                          <!-- <div class="cbt"> 
                              <div class="cbt__question"><span>1.</span>객체지향 프로그램에서 데이터를 추상화하는 단위는?</div>
                              <div class="cbt__question__img"><img src="img2/2020-02-01.jpg" alt="정보처리기능사 1회 문제?"></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__keyword">객체지향언어</div>
                          </div>
                          <div class="cbt">
                              <div class="cbt__question">2.다음 빈칸을 채우시오</div>
                              <div class="cbt__question__desc">객체지향 언어는 ______이다.</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__keyword">객체지향언어</div>
                          </div>
                          <div class="cbt">
                              <div class="cbt__question">객체지향 프로그램에서 데이터를 추상화하는 단위는?</div>
                              <div class="cbt__question__img">여기는 이미지가 있으면 들어옵니다.</div>
                              <div class="cbt__question__desc">객체지향 언어는 ______이다.</div>
                              <div class="cbt__selects">
                                  <div>
                                      <input type="radio" id="select1" >
                                      <label for="select1">클래스</label>
                                  </div>
                                  <div>
                                      <input type="radio" id="select2">
                                      <label for="select2">메소드</label>
                                  </div>
                                  <div>
                                      <input type="radio" id="select3" >
                                      <label for="select3">상속</label>
                                  </div>
                                  <div>
                                      <input type="radio" id="select4" >
                                      <label for="select4">메시지</label>
                                  </div>
                              </div>
                              <div class="cbt__desc">객체지향언어는 이다.</div>
                              <div class="cbt__keyword">객체지향언어</div>
                          </div>
                          <div class="cbt">
                              <div class="cbt__question">객체지향 프로그램에서 데이터를 추상화하는 단위는?</div>
                              <div class="cbt__question__img">여기는 이미지가 있으면 들어옵니다.</div>
                              <div class="cbt__question__desc">객체지향 언어는 ______이다.</div>
                              <div class="cbt__selects">
                                  <div>
                                      <input type="radio" id="select1" >
                                      <label for="select1">클래스</label>
                                  </div>
                                  <div>
                                      <input type="radio" id="select2">
                                      <label for="select2">메소드</label>
                                  </div>
                                  <div>
                                      <input type="radio" id="select3" >
                                      <label for="select3">상속</label>
                                  </div>
                                  <div>
                                      <input type="radio" id="select4" >
                                      <label for="select4">메시지</label>
                                  </div>
                              </div>
                              <div class="cbt__desc">객체지향언어는 이다.</div>
                              <div class="cbt__keyword">객체지향언어</div>
                          </div> -->
                  </div>
                   </div>
                   
                   <!-- 남은 시간 59분 10초
                </div>
                <div class="cbt__sumit">답안지 제출하기</div>
            </div>
            <div>
                 <div class="cbt__title">수험자 : <em></em></div>
                 <div class="cbt__score">
                     <span>전체 문제수 : <em>60</em>문항</span>
                     <span>남은 문제수 : <em>59</em>문항</span>
                 </div>
            </div> -->

               </div>
               <div class="cbt__aside">
                   <div class="cbt__time2">
                     <div class="cbt__box">
                         <div class="time2__box">
                             <em class="time2__img"></em><span>59분 10초</span>
                         </div>
                         <div class="submit__box">
                             <strong class="submit__img"></strong><em class="submit">답안지 제출하기</em>
                         </div>
                     </div>
                   </div>
                   <div class="cbt__info">
                       <div class="title">수험자 : 안교남</div>
                       <div class="score">
                           <span class="full__score">전체 문제수 : 60문항</span>
                           <span class="odd__score">남은 문제수 : 59문항</span>
                       </div>
                   </div>
                   <div class="cbt__omr">
                       <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>
          </div>
        </div>
    </main>
    <!-- //main -->

    <!-- <footer id="footer">
        <a href="skadldldl123@gmail.com">mailto:skadldldl123@gmail.com</a>
    </footer> -->
    <!-- //footer -->
    </body>

코드설명

1. div태그 .container은 내용물들을 가운데로 옮겨주고. 반응형을 위해서 특정 max-width에서 퍼센트(%)을 줍니다.

2. div태그 .cbt__header은 "시험 종목", "남은 시간", "답안지 제출하기"를 담고 있습니다.

3. div태그 .cbt__header안에 있는 h2태그는  

JAVASCRIPT코드

<script>
const cbtQuiz = document.querySelector(".cbt__quiz");
const omr = [];
const cbtOmr = document.querySelector(".cbt__omr");
let questionAll = [];  //모든 퀴즈 정보
const cbt__submit = document.querySelector(".cbt__time2 .submit");
const fullScore = document.querySelector(".full__score");
const oddScore = document.querySelector(".odd__score");

// 데이터 가져오기
const dataQuestion = () => {
    // 가져온 다음에 처리함
    // .then.then 체인기능
    fetch("json/gisa2020_01.json") //json파일을 읽어 오고
    // then(res => res.json)에서 res는 이름을 마음대로 설정 가능.
    .then(res => res.json()) //json파일을 객체로 변환합니다.
    // items에 파일 안의 내용이 전부 저장되어있음
    .then(items => { //객체를 출력합니다
        // console.log(items);      

        questionAll = items.map((item, index, array) => {
            const formatedQuestion = {
                Question: item.question,
                Number : index+1,
                choice1: "정답",
                choice2: "오답",
                choice3: "오답",
                choice4: "오답"
            }
            // ...item을 써서 데이터만을 불러옴
            const answerChices = [...item.incorrent_answer];
            console.log(item.incorrect_answers);
            // 정답체크
            // 정답 랜덤으로 불러오기
            // console.log(answerChices.length); // 3나옴
            // 상수 formatedQuestion에다가 answer이라는 키값을 부여함.
            formatedQuestion.answer = Math.floor(Math.random() * answerChices.length) +1;
            // console.log(Math.floor(Math.random() * answerChices.length));
            // 정답을 랜덤으로 추가
            answerChices.splice(formatedQuestion.answer-1, 0, item.correct_answer);

            // 보기를 추가
            answerChices.forEach((choice, index) => {
                // 보기 3개 + 정답 1개 가져옴
                // 0,1,2,3까지 갖고 오고
                // console.log("알려줘~:",choice, index);
                formatedQuestion["choice" + (index+1)] = choice;
            });

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

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

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

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



            const cbtselects2 = document.querySelectorAll(".cbt__aside .cbt__omr input");
            const cbtselects3 = document.querySelectorAll(".cbt__aside .cbt__omr label");
            let i = 0;
            // console.log(cbtselects3);

            cbtselects2.forEach((el, index) => {
                if(cbtselects2[index].checked == true){
                    console.log("ac");
                }
                else{
                    oddScore.innerHTML = "남은 문제수 : " + (i+=1) + "문항";
                    console.log("체크?"+el.checked);
                    // console.log("???")
                }
                // console.log("벨류"+cbtselects2[index].value);
            });

            // 남은 문제수 : 59문항


            // 리턴값 없이 questionAll 호출하면 undefinde가 나옴
            // console.log(formatedQuestion);
            return formatedQuestion;
        });

        newQuestion(); // 문제 만들기 
        // console.log(questionAll);
    })//.catch((err) => console.log(err));

};

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

    // console.log(questionAll);
    questionAll.forEach((question, number) => {
        // console.log(question);
        exam.push(`
            <div class="cbt"> 
                <div class="cbt__question"><span>${number+1}</span>. ${question.Question}</div>
                <div class="cbt__question__img"></div>
                <div class="cbt__selects">
                        <input type="radio" id="select${number}_1" name="select${number}" value="${number+1}_1" 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}_2" 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}_3" 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}_4" onclick="answerSelect(this)">
                        <label for="select${number}_4"><span>${question.choice4}</span></label>
                </div>
                <div class="cbt__desc hide">${question.desc}</div>
                <div class="cbt__keyword">${question.keyword}</div>
            </div>
        `);
        cbtQuiz.innerHTML = exam.join("");

        omr.push(`
          <div class="cbt__omr">
               <div class="cbt__omr">
                   <div class="omr">
                       <strong>${number+1}</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>
               </div>
           </div>
           `);
        });
        cbtQuiz.innerHTML = exam.join("");
        cbtOmr.innerHTML = omr.join(""); 
    }


// 정답 확인
// em.submit
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;

        if(numberAnswer == question.answer){
            console.log("정답");
            cbtselects[number].parentElement.classList.add("good");
            // 전체 문제수 : 60문항
        } 
        else {
            console.log("모야");
            cbtselects[number].parentElement.classList.add("bad");

            const label = cbtselects[number].querySelectorAll("label");
            label[question.answer-1].classList.add("corrent");
        }
        const quizDesc = document.querySelectorAll(".cbt__desc");

        if(quizDesc[number].innerText == "undefined"){
            quizDesc[number].classList.add("hide");
        }else {
            quizDesc[number].classList.remove("hide");
        }
    });
}

const answerSelect = () => {
};


cbt__submit.addEventListener("click", answerQuiz);
// cbt__submit.addEventListerner("click", answerQuiz);
// console.log(answerQuiz);

dataQuestion();

</script>

코드설명

2.

 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(userAnswer.split("_")[1]);

    if(numberAnswer == question.answer){
        console.log("정답");
        cbtselects[number].parentElement.classList.add("good");
        // 전체 문제수 : 60문항
    } 
    else {
        console.log("모야");
        cbtselects[number].parentElement.classList.add("bad");

        const label = cbtselects[number].querySelectorAll("label");
        label[question.answer-1].classList.add("corrent");
    }
    const quizDesc = document.querySelectorAll(".cbt__desc");

    if(quizDesc[number].innerText == "undefined"){
        quizDesc[number].classList.add("hide");
    }else {
        quizDesc[number].classList.remove("hide");
    }
});

정답을 확인하는 코드로 

input타입에 체크가 되어있으면 확인 후 정답과 비교해서 CSS style을 변경합니다.

 

3.

const answerSelect = () => {
};

cbt__submit.addEventListener("click", answerQuiz);
// cbt__submit.addEventListerner("click", answerQuiz);
// console.log(answerQuiz);

dataQuestion();

버튼을 클릭하면 answerQuiz함수를 실행시킵니다.

hasOwnProperty 자바스크립트의 내장 메소드 중 하나로, 객체가 특정한 속성을 가지고 있는지 여부를 판단할 수 있습니다. 이 메소드는 객체의 속성 중에서 해당 속성이 객체의 고유 속성인지를 판단하여, 상속받은 속성은 포함하지 않습니다.
Math 자바스크립트의 내장 객체 중 하나로, 수학적인 연산을 수행하는 메소드와 상수들을 제공합니다. 이 객체는 전역 객체이므로 어디서든 접근이 가능합니다.
Math.random() 0 이상 1 미만의 난수를 반환합니다.
Math.floor(x) 인자 x보다 작거나 같은 최대 정수를 반환합니다.