My Melody Kawaii

JAVASCRIPT/퀴즈 이펙트

여러문제가 포함 되어있는 퀴즈를 만들어보자!

younajeong 2023. 3. 14. 13:21

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

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

퀴즈 이펙트

저번 퀴즈에 이어서 3번째 이번에는 여러 문제가 포함되어있는 퀴즈 사이트를 만들어 봤습니다!

 

 

HTML코드

<!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>퀴즈 이펙트03</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="quizEffext01.html">1</a></li>
            <li><a href="quizEffext02.html">2</a></li>
            <li class="active"><a href="quizEffext03.html">3</a></li>
            <li><a href="quizEffext04.html">4</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">
                        <em></em>. <span></span> 
                    </div>
                    <div class="quiz__view">
                        <div class='dog__wrap'>
                            <div class="ture">정답입니다!</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__answer">
                        <input class="input" type="text" placeholder="정답을 적어주세요!">
                        <button class="confirm">정답확인하기</button>
                        <div class="result"></div>
                    </div>
                    <div class="quiz__desc"></div>
                </div>
            </div>
            <div class="quiz">
                <div class="quiz__header">
                    <h2 class="quiz__title"></h2>
                </div>
                <div class="quiz__main">
                    <div class="quiz__question">
                        <em></em>. <span></span> 
                    </div>
                    <div class="quiz__view">
                        <div class='dog__wrap'>
                            <div class="ture">정답입니다!</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__answer">
                        <input class="input" type="text" placeholder="정답을 적어주세요!">
                        <button class="confirm">정답확인하기</button>
                        <div class="result"></div>
                    </div>
                    <div class="quiz__desc"></div>
                </div>
            </div>
            <div class="quiz">
                <div class="quiz__header">
                    <h2 class="quiz__title"></h2>
                </div>
                <div class="quiz__main">
                    <div class="quiz__question">
                        <em></em>. <span></span> 
                    </div>
                    <div class="quiz__view">
                        <div class='dog__wrap'>
                            <div class="ture">정답입니다!</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__answer">
                        <input class="input" type="text" placeholder="정답을 적어주세요!">
                        <button class="confirm">정답확인하기</button>
                        <div class="result"></div>
                    </div>
                    <div class="quiz__desc"></div>
                </div>
            </div>
        </div>
    </main>
        </div>
    </main>
        </div>
    </main>
    <!-- //main -->
    

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

HTML들여다보기

  • 퀴즈 사이트 2번과 똑같이 복사해서 붙여주는데 여러가지 퀴즈를 만들 예정이라 class="quize"부분을 2개 더 추가 해줍니다.

 

 

CSS코드

.quiz__desc {
    border-top: 6px ridge #cacaca;
    padding: 20px;
    font-family: 'suncheon';
    background-color: #fffae4;
}
.quiz__desc::before {
    content: "✔️Tip ";
    color: #ff5050;
    font-weight: bold;
}

CSS들여다보기

  • 저번 퀴즈 효과처럼 전체 CSS를 가져 온후 quiz__desc를 추가해줍니다. 
  • before가상요소를 추가 해줍니다.

 

JAVASCRIPT

<script>
        // 선택자
        const quizWrap = document.querySelector(".quiz__wrap");
        const quizTitle = quizWrap.querySelectorAll(".quiz__title");                    //시험 종목 + 시간
        const quizQuestionNum = quizWrap.querySelectorAll(".quiz__question em");        //문제 번호
        const quizQuestion = quizWrap.querySelectorAll(".quiz__question span");         //문제 질문
        const quizAnswerResult = quizWrap.querySelectorAll(".quiz__answer .result");    //문제 정답
        const quizDesc = quizWrap.querySelectorAll(".quiz__desc");                      //문제 설명
        const quizAnswerConfirm = quizWrap.querySelectorAll(".quiz__answer .confirm");  //정답 버튼
        const quizAnsweInput = quizWrap.querySelectorAll(".quiz__answer .input");       //사용자 정답
        const dogWrap = quizWrap.querySelectorAll (".dog__wrap");

        // 문제 정보
        const quizinfo = [
        {
            infoType: "정보처리 기능사",
            infoTime: "2011년 4회",
            infoNumber: "1",
            infoQuestion: "주파수분할 다중화 방식에서 각 채널간 간섭을 막기 위해서 일종의 완충지역 역할을 하는 것을 무엇이라고 하는가?",
            infoAnswer: "가드밴드",
            infoDesc: "가드밴드(Guard Band)는 주파수분할 다중화 방식에서 각 채널간 간섭을 막기 위해서 일종의 완충지역 역할을 한다.",
        },{
            infoType: "정보처리 기능사",
            infoTime: "2011년 4회",
            infoNumber: "2",
            infoQuestion: "사용자의 명령으로 시스템이 수행되고 그에 따른 결과를 나타내 주는 대화식 운영체제는 무엇인가?",
            infoAnswer: "UNIX",
            infoDesc: "UNIX는 사용자의 명령으로 시스템이 수행되고 그에 따른 결과를 나타내 주는 대화식 운영체제이다.",
        },{
            infoType: "정보처리 기능사",
            infoTime: "2011년 4회",
            infoNumber:  "3",
            infoQuestion: "프로세스들이 서로 다른 프로세스가 차지하고 있는 자원을 무한정 기다려 시스템이 멈춘 것처럼 보이는 상태는 무엇일까?",
            infoAnswer: "교착상태",
            infoDesc: "교착상태(Deadlock)는 2개 이상의 프로세스들이 서로 다른 프로세스가 차지하고 있는 자원을 무한정 기다려 시스템이 멈춘 것처럼 보이는 현상이다.",
        }
    ];

    // 문제 출력 (다중이)
    //#1 // 문제 종류 
    // quizTitle[0].textContent = quizinfo[0].infoType;
    // quizTitle[1].textContent = quizinfo[1].infoType;
    // quizTitle[2].textContent = quizinfo[2].infoType;

    // //문제 시간 
    // quizTime[0].textContent = quizinfo[0].infoTime;
    // quizTime[1].textContent = quizinfo[1].infoTime;
    // quizTime[2].textContent = quizinfo[2].infoTime;

    // //문제 번호
    // quizQuestionNum[0].textContent = quizinfo[0].infoNumber;
    // quizQuestionNum[1].textContent = quizinfo[1].infoNumber;
    // quizQuestionNum[2].textContent = quizinfo[2].infoNumber;

    // //문제 질문
    // quizQuestion[0].textContent = quizinfo[0].infoQuestion;
    // quizQuestion[1].textContent = quizinfo[1].infoQuestion;
    // quizQuestion[2].textContent = quizinfo[2].infoQuestion;

    // //문제 정답
    // quizAnswerResult[0].textContent = quizinfo[0].infoAnswer;
    // quizAnswerResult[1].textContent = quizinfo[1].infoAnswer;
    // quizAnswerResult[2].textContent = quizinfo[2].infoAnswer;

    // //문제 해설
    // quizDesc[0].textContent = quizinfo[0].infoDesc;
    // quizDesc[1].textContent = quizinfo[1].infoDesc;
    // quizDesc[2].textContent = quizinfo[2].infoDesc;

    // #2 for문 문제출력 
    // 문제 종류 + 문제 시간 
    // quizTitle[0].innerHTML = quizinfo[0].infoType + " " + quizinfo[0].infoTime;  
    // quizTitle[1].innerHTML = quizinfo[1].infoType + " " + quizinfo[1].infoTime;
    // quizTitle[2].innerHTML = quizinfo[2].infoType + " " + quizinfo[2].infoTime;

    // quizQuestionNum[0].textContent = quizinfo[0].infoNumber;
    // quizQuestionNum[1].textContent = quizinfo[1].infoNumber;
    // quizQuestionNum[2].textContent = quizinfo[2].infoNumber;

    // quizQuestion[0].textContent = quizinfo[0].infoQuestion;
    // quizQuestion[1].textContent = quizinfo[1].infoQuestion;
    // quizQuestion[2].textContent = quizinfo[2].infoQuestion;

    // for (let i=0; i<quizinfo.length; i++){
    //     quizTitle[i].innerHTML = quizinfo[i].infoType + " " + quizinfo[i].infoTime;
    //     quizQuestionNum[i].textContent = quizinfo[i].infoNumber;
    //     quizQuestion[i].textContent = quizinfo[i].infoQuestion;
    //     quizAnswerResult[i].textContent = quizinfo[i].infoAnswer;
    //     quizDesc[i].textContent = quizinfo[i].infoDesc;
    // }

    quizinfo.forEach(function(e, i){      // 인덱스 값으로 쓰고 싶으면 앞에 엘리먼트 값을 써야함
        quizTitle[i].innerHTML = quizinfo[i].infoType + " " + quizinfo[i].infoTime;
        quizQuestionNum[i].textContent = quizinfo[i].infoNumber;
        quizQuestion[i].textContent = quizinfo[i].infoQuestion;
        quizAnswerResult[i].textContent = quizinfo[i].infoAnswer;
        quizDesc[i].textContent = quizinfo[i].infoDesc;
        
    });

    // 정답 숨기기 
    // quizAnswerResult[0].style.display = "none";
    // quizAnswerResult[1].style.display = "none";
    // quizAnswerResult[2].style.display = "none";

    // quizDesc[0].style.display = "none";
    // quizDesc[1].style.display = "none";
    // quizDesc[2].style.display = "none";

    // for(let i=0; i<quizinfo.length; i++){
    //     quizAnswerResult[i].style.display = "none";
    //     quizDesc[i].style.display = "none";
    // }

    quizinfo.forEach(function(e, i){
        quizAnswerResult[i].style.display = "none";
        quizDesc[i].style.display = "none";
    });

    //정답 확인
    quizAnswerConfirm.forEach(function(btn, num){       //다중이기 때문에 num을 사용한다.
        btn.addEventListener("click",function(){
            //사용자 정답 
            const userAnswer = quizAnsweInput[num].value;    
            quizAnsweInput[num].style.display = "none";             //인풋박스 숨김
            quizAnswerConfirm[num].style.display = "none";         //정답 확인 버튼 숨김
            quizAnswerResult[num].style.display = "block";         //정답 보이기
            quizDesc[num].style.display = "block";                 //해설 보이기 
            
            
            //사용자 정답 == 문제 정답
            if(userAnswer == quizinfo[num].infoAnswer){
                dogWrap[num].classList.add("like");
            }else {
                dogWrap[num].classList.add("dislike");
            }
                
        });
    });


    
    </script>

Javascript 들여다보기

  • 스크립트를 사용해서 퀴즈를 완성을 할 예정입니다.
  • 퀴즈 2에서 한것처럼 선택자를 만들어준 후 문제 정보를 const quizinfo로 총 3개로 만들어 줍니다.
  • 퀴즈 2처럼 문제종류, 문제시간, 문제번호,  문제질문, 문제정답, 문제해설을 스크립트합니다. 3가지씩 있으니까 배열안에 객체를 가져오는 방법일 사용해서 문제를 출력합니다.                                                                                                           quizTitle[0].textContent = quizinfo[0].infoType;
     quizTitle[1].textContent = quizinfo[1].infoType;
      quizTitle[2].textContent = quizinfo[2].infoType;
  • 문제를 출력해보니 소스들이 너무 많아지고 지저분해졌는데 for문을 이용해서 문제를 출력합니다.
  • for문으로 문제를 출력하기 전에 문제종류 + 문제 시간을 먼저 합쳐 줍니다. quizTitle[0].innerHTML = quizinfo[0].infoType + " " + quizinfo[0].infoTime;
  • for문을 이용해서  문제종류+시간, 번호,질문,정답,해설을 출력해줍니다.
  • for문을 forEach문으로 바꿔줄 수 있는데 바꿔줄 때는 forEach앞에 quizinfo라는 값을 먼저 입력해서 function을 사용해서 값을 출력 해주는데 [i]라는 인덱스 값을 출력하기 때문에 앞에 'e'엘리먼트 값을 써줘야 출력이 가능하게 됩니다.quizinfo.forEach(function(e, i)
  • 정답확인을 위해 다시한번 forEach문을 사용해주는데 다중이기 때문에 num을 사용해 줍니다.
  • 사용자 정답을 위해 userAnswer라는 선택자를 만들어 준 후 인풋박스 숨김,정답확인 버튼 숨김, 정답보이기,해설보이기를 만들어 줍니다.
  • 그리고 if문을 사용해서 사용자 정답이 문제 정답과 같을 때 다를 때의 값을 설정해 줍니다.

 

 

몰랐던 속성들

  • querySelectorAll : 오늘 3번에서 배웠던 부분에서 가장 중요한 부분인데 선택자가 다중선택을 할 수 있게 해줄 수 있습니다.
  • innerHTML: TML 및 XML 문서의 DOM API에서 Element 인터페이스의 속성(property) 중 하나입니다. 이를 사용하여 HTML 콘텐츠를 가져오거나 설정할 수 있습니다.