Bomb Kirby Running

JAVASCRIPT

자바스크립트 퀴즈 이펙트 5

^. ̫ .^ 2023. 3. 25. 14:26

728x90

 

오늘은 저번에 만든 퀴즈 이펙트 4번처럼 객관식 유형을 선택할 수 있는 퀴즈 유형을 만들겁니다.

4번을 이용해서 오늘은 더 많은 문제를 선택할 수 있는 유형을 만들어보도록 하겠습니다.

 

 

 

코드

<!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>퀴즈 이펙트05</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="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 class="active"><a href="quizEffect05.html">5</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"></div>
                    <div class="quiz__view">
                        <div class="dog_wrap">
                            <div class="true">정답입니다!</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__choice">
                        <label for="choice1">
                            <input type="radio" id="choice1" name="choice" class="select" value="1">
                            <span></span>
                        </label>
                        <label for="choice2">
                            <input type="radio" id="choice2" name="choice" class="select" value="2">
                            <span></span>
                        </label>
                        <label for="choice3">
                            <input type="radio"id="choice3" name="choice" class="select" value="3">
                            <span></span>
                        </label>
                        <label for="choice4">
                            <input type="radio"id="choice4" name="choice" class="select" value="4">
                            <span></span>
                        </label>
                    </div>
                    <div class="quiz__answer">
                        <button class="confirm">정답 확인하기</button>
                    </div>
                    <div class="quiz__desc">
                    </div>
                </div>
            </div> -->    
        </div>
    </main>
    <!-- //main -->
    <footer id="footer">
        <a href="mailto:1346zany@gmail.com">1346zany@gmail.com</a>
    </footer>
    <!-- //footer -->
</body>
</html>

4번에 있는 코드 구성과 똑같으므로 4번을 그대로 가져왔습니다.

다만, 이번엔 여러 개의 퀴즈를 만들것이므로 main부분이 아닌 script에 퀴즈 정보들을 넣을 것 입니다.

그래서 quiz__wrap안에 있는 부분들은 모두 주석처리 해주었습니다.

 

 

CSS

각각의 CSS를 참고해주세요.

 

reset.css

@import url('https://webfontworld.github.io/DungGeunMo/DungGeunMo.css');
@import url('https://webfontworld.github.io/suncheon/Suncheon.css');

* {
    margin: 0;
    padding: 0;
}
*, *::before, *::after {
    box-sizing: border-box;
  }
a {
    text-decoration: none;
    color: #222;
}
h1,h2,h3,h4,h5,h6 {
    font-weight: normal;
}
li, ul, ol {
    list-style: none;
}
img {
    vertical-align: top;
    width: 100%;
}
em {
    font-style: normal;
}
body {
    background:
        radial-gradient(#a4a4a4 3px, transparent 4px),
        radial-gradient(#a4a4a4 3px, transparent 4px),
        linear-gradient(#fff 4px, transparent 0),
        linear-gradient(45deg, transparent 74px, transparent 75px, #a4a4a4 75px, #a4a4a4 76px, transparent 77px, transparent 109px),
        linear-gradient(-45deg, transparent 75px, transparent 76px, #a4a4a4 76px, #a4a4a4 77px, transparent 78px, transparent 109px),
        #fff;
    background-size: 109px 109px, 109px 109px, 100% 6px, 109px 109px, 109px 109px;
    background-position: 54px 55px, 0px 0px, 0px 0px, 0px 0px, 0px 0px;
}

 

quiz.css

/* header */
#header {
    position: fixed;
    left: 0;
    top: 0;
    background-color: #262626;
    color: #fff;
    padding: 10px;
    width: 100%;
    z-index: 1000;
    display: flex;
    justify-content: space-between;
}
#header::before {
    content: '';
    border: 4px ridge #a3a3a3;
    position: absolute;
    left: 5px;
    top: 5px;
    width: calc(100% - 10px);
    height: calc(100% - 10px);
}
#header h1 {
    font-size: 28px;
    padding: 5px 5px 5px 10px;
    font-family: 'DungGeunMo';
    z-index: 10;
    position: relative;
}
#header h1 a {
    color: #fff;
}
#header h1 em {
    font-size: 0.5em;
}
#header ul {
    padding: 5px;
}
#header li {
    display: inline;
    z-index: 10;
    position: relative;
}
#header li a {
    color: #fff;
    font-family: 'DungGeunMo';
    border: 1px dashed #fff;
    display: inline-block;
    padding: 5px;
}
#header li.active a,
#header li a:hover {
    background-color: #fff;
    color: #000;
}
/* footer */
#footer {
    position: fixed;
    left: 0;
    bottom: 0;
    width: 100%;
    background-color: #262626;
    text-align: center;
}
#footer a {
    color: #fff;
    padding: 20px;
    display: block;
    font-family: 'DungGeunMo';
    z-index: 10;
    position: relative;
}
#footer::before {
    content: '';
    border: 4px ridge #a3a3a3;
    position: absolute;
    left: 5px;
    top: 5px;
    width: calc(100% - 10px);
    height: calc(100% - 10px);
}
#main {
    padding: 100px 0;
}
/* quiz__wrap */
.quiz__wrap {
    display: flex;
    justify-content: center;
    flex-wrap: wrap;
    align-items: flex-start;
}
.quiz__wrap .quiz {
    width: 500px;
    background-color: #fff; 
    border: 8px ridge #cacaca;
    margin: 10px;
}
.quiz__title {
    background-color: #cacaca;
    border: 3px ridge #cacaca;
    border-bottom-width: 6px;
    padding: 5px;
    font-family: 'DungGeunMo';
    font-size: 16px;
    color:#3b3b3b;
    text-align: center;
}
.quiz__question {
    padding: 20px;
    font-size: 24px;
    font-family: 'Suncheon';
    font-weight: 300;
    line-height: 1.4;
    border-bottom: 6px ridge #cacaca;
}
.quiz__question em {
    color: #55a8f7;
}
.quiz__answer {
    font-family: 'Suncheon';
    padding: 20px;
    text-align: center;
    font-size: 24px;
    /* border-bottom: 6px ridge #cacaca; */
}
.quiz__answer .confirm {
    background-color: #8cbaff;
    border: 6px ridge #cacaca;
    width: 100%;
    font-family: 'Suncheon';
    padding: 10px 20px;
    font-size: 22px;
    cursor: pointer;
    transition: all 0.3s;
    font-weight: bold;
}
.quiz__answer .confirm:hover {
    background-color: #7cd5ff;
}
.quiz__answer .result {
    background-color: #fff;
    border: 6px ridge #cacaca;
    width: 100%;
    font-family: 'Suncheon';
    padding: 10px 20px;
    font-size: 22px;
}
.quiz__answer .input{
    background-color: #fff;
    border: 6px groove #cacaca;
    width: 100%;
    font-family: 'Suncheon';
    padding: 10px 20px;
    font-size: 22px;
    margin-bottom: 10px;
}
.quiz__view {
    border-bottom: 6px ridge #cacaca;
    overflow: hidden;
}
.quiz__desc {
    border-top: 6px ridge #cacaca;
    padding: 20px;
    font-family: 'Suncheon';
    background-color: #f5f5f5f5;
}
.quiz__desc::before {
    content:  "👍 Tip ";
    color: #ff3c3c;
    font-weight: bold;
}
.quiz__choice {
    padding: 20px;
    border-bottom: 6px ridge #cacaca;
    font-family: 'Suncheon';
}
.quiz__choice label {
    display: flex;
}
.quiz__choice label input {
    position:absolute;
    clip:rect(0 0 0 0);
    width:1px;
    height:1px;
    margin:-1px;
    overflow:hidden;
}
.quiz__choice label span {
    font-size: 20px;
    line-height: 1.4;
    padding: 6px;
    display: flex;
    cursor: pointer;
    margin: 2px 0;
}
.quiz__choice label span::before {
    content: '';
    width: 26px;
    height: 26px;
    border-radius: 50%;
    margin-right: 15px;
    background: #fff;
    box-shadow: inset 0 0 0 4px #57d1f0;
    transition: all 0.2s;
    flex-shrink: 0;
}
.quiz__choice label input:checked + span {
    background-color: #edf9fc;
}
.quiz__choice label input:checked + span::before { 
    box-shadow: inset 0 0 0 8px #57d1f0;
}
.quiz__check {
    position: fixed;
    right: 20px;
    bottom: 20px;
    width: 130px;
    height: 130px;
    line-height: 130px;
    border-radius: 50%;
    z-index: 1000;
    text-align: center;
    background: #0294e9;
    color: #fff;
    font-family: 'Suncheon';
    cursor: pointer;
}
.quiz__info {
    position: fixed;
    right: 20px;
    bottom: 170px;
    background-color: #79e2fc;
    text-align: center;
    width: 130px;
    height: 50px;
    line-height: 50px;
    border-radius: 10px;
    font-family: 'Suncheon';
    color: #fff;
}
.quiz__info::after {
    content: '';
    position: absolute;
    left: 50%;
    margin-left: -10px;
    bottom: -10px;
    border-top: 10px solid #79e2fc;
    border-left: 10px solid transparent;
    border-right: 10px solid transparent;
}
/* dog_wrap */
.dog .tail, 
.dog .chin, 
.dog .tongue::before, 
.dog .tongue::after, 
.dog .mouth, 
.dog .nose, 
.dog .teardrop, 
.dog .eyes, 
.dog .face::before, 
.dog .face::after, 
.dog .ears::before, 
.dog .ears::after, 
.dog_wrap {
    transition: 0.2s ease-in;
}
.dog_wrap{
    position: relative;
}
.dog_wrap .true {
    width: 120px;
    height: 120px;
    line-height: 120px;
    background-color: hsl(199, 81%, 69%);
    border-radius: 50%;
    text-align: center;
    color: #fff;
    position: absolute;
    left: 70%;
    top: 100px;
    font-family: 'Suncheon';
    opacity: 0;
}
.dog_wrap .false {
    width: 120px;
    height: 120px;
    line-height: 120px;
    background-color: #4f52f5;
    border-radius: 50%;
    text-align: center;
    color: #fff;
    position: absolute;
    right: 70%;
    top: 100px;
    font-family: 'Suncheon';
    opacity: 0;
}
.dog_wrap.like .true {
    opacity: 1;
    animation: wobble 0.6s;
}
.dog_wrap.dislike .false {
    opacity: 1;
    animation: wobble 0.6s;
}
@keyframes wobble {
    0%{transform: translateX(0) rotate(0deg);}
    15%{transform: translateX(-25%) rotate(-5deg);}
    30%{transform: translateX(20%) rotate(3deg);}
    45%{transform: translateX(-15%) rotate(-3deg);}
    60%{transform: translateX(10%) rotate(2deg);}
    75%{transform: translateX(-5%) rotate(-1deg);}
    100%{transform: translateX(0) rotate(0deg);}
}
.card-container {
    position: relative;
    width: 360px;
    height: 378px;
    margin: auto;
    padding-top: 125px;
    border-radius: 3%;
    z-index: 0;
}
.card-container::before, .card-container::after {
    content: "";
    position: absolute;
    height: 100%;
    margin: auto;
    left: 0;
    right: 0;
    border-radius: 3%;
    z-index: -1;
}
.dog .head,
.dog .body {
    position: relative;
    width: 115px;
}
.dog .head {
    height: 115px;
    border-radius: 50% 50% 0 0;
    margin: 0 auto;
}
.dog .ears {
    position: relative;
    top: -14%;
    width: 100%;
}
.dog .ears::before, .dog .ears::after {
    content: "";
    position: absolute;
    top: 0;
    width: 35px;
    height: 70px;
    background: #CB7A1D;
    border-top: 11px solid #F7AA2B;
    border-left: 7px solid #F7AA2B;
    border-right: 7px solid #F7AA2B;
}
.dog .ears::before {
    left: 0;
    border-radius: 50% 45% 0 0;
}
.dog .ears::after {
    right: 0;
    border-radius: 45% 50% 0 0;
}
.dog .face {
    position: absolute;
    background: #F7AA2B;
    width: 100%;
    height: 100%;
    border-radius: 50% 50% 0 0;
}
.dog .face::before, .dog .face::after {
    content: "";
    display: block;
    margin: auto;
    background: #FEFEFE;
}
.dog .face::before {
    width: 15px;
    height: 35px;
    margin-top: 24px;
    border-radius: 20px 20px 0 0;
}
.dog .face::after {
    position: absolute;
    bottom: -1px;
    left: 0;
    right: 0;
    width: 60px;
    height: 65px;
    border-radius: 45% 45% 0 0;
}
.dog .eyes {
    position: relative;
    top: 29%;
    text-align: center;
}
.dog .eyes::before, .dog .eyes::after {
    content: "";
    display: inline-block;
    width: 12px;
    height: 12px;
    border-radius: 100%;
    background: #451d1c;
    margin: 0 14.5%;
}
.dog .teardrop {
    position: absolute;
    top: 125%;
    left: 19%;
    width: 6px;
    height: 6px;
    border-radius: 0 50% 50% 50%;
    transform: rotate(45deg);
    background: #FEFEFE;
    visibility: hidden;
}
.dog .nose {
    position: relative;
    top: 35%;
    width: 16px;
    height: 8px;
    border-radius: 35px 35px 65px 65px;
    background: #451d1c;
    margin: auto;
}
.dog .mouth {
    position: relative;
    top: 34.5%;
    width: 4px;
    height: 6px;
    margin: 0 auto;
    text-align: center;
    background: #451d1c;
}
.dog .mouth::before, .dog .mouth::after {
    content: "";
    position: absolute;
    top: -4px;
    width: 18px;
    height: 18px;
    border-radius: 50%;
    border: 4px solid #451d1c;
    border-left-color: transparent;
    border-top-color: transparent;
    z-index: 2;
}
.dog .mouth::before {
    transform: translateX(-89%) rotate(45deg);
}
.dog .mouth::after {
    transform: translateX(-2px) rotate(45deg);
}
.dog .tongue {
    position: relative;
    z-index: 1;
}
.dog .tongue::before, .dog .tongue::after {
    content: "";
    position: absolute;
}
.dog .tongue::before {
    top: 10px;
    left: -7px;
    width: 18px;
    height: 0;
    border-radius: 50%;
    background: #451d1c;
    z-index: -1;
}
.dog .tongue::after {
    top: 14px;
    left: -4px;
    width: 12px;
    height: 0;
    border-radius: 20px;
    background: #F5534F;
    z-index: 5;
}
.dog .chin {
    position: relative;
    top: 47.5%;
    margin: 0 auto;
    width: 12px;
    height: 12px;
    border-top: 10px solid #e8e7ec;
    border-left: 5px solid transparent;
    border-right: 5px solid transparent;
    border-radius: 2px;
    z-index: 0;
}
.dog .body {
    position: relative;
    height: 139px;
    margin: auto;
    z-index: 0;
}
.dog .body::before, .dog .body::after {
    content: "";
    position: absolute;
    top: -1px;
    left: 0;
    right: 0;
    bottom: 0;
    display: block;
    width: 100%;
    margin: auto;
    background: #F7AA2B;
}
.dog .body::after {
    top: -2px;
    bottom: -1px;
    width: 60px;
    background: #FEFEFE;
}
.dog .tail {
    position: absolute;
    left: -60%;
    bottom: 1px;
    background: #F7AA2B;
    width: 93px;
    height: 15px;
    transform: rotate(45deg);
    transform-origin: 100% 50%;
    border-radius: 25px 0 0 25px;
    z-index: -2;
}
.dog .legs {
    position: absolute;
    bottom: 0;
    left: -10%;
    width: 120%;
    height: 15%;
    background: #F7AA2B;
    border-radius: 10px 10px 0 0;
}
.dog .legs::before, .dog .legs::after {
    content: "";
    position: absolute;
    bottom: 1px;
    background: #CB7A1D;
    z-index: -1;
}
.dog .legs::before {
    left: -7.5%;
    width: 115%;
    height: 55%;
    border-radius: 5px 5px 0 0;
}
.dog .legs::after {
    left: -3.5%;
    width: 107%;
    height: 250%;
    border-radius: 20px 20px 35px 35px;
}  
@keyframes movetongue {
    100% {
        height: 27px;
    }
}

@keyframes movetail {
    0% {
      transform: rotate(37deg);
    }
    100% {
      transform: rotate(52deg);
    }
}

@keyframes cry {
    100% {
      visibility: visible;
    }
}


.like {
    background: #a0ebfd;
}
.like .face::before {
    margin-top: 10px;
}
.like .face::after {
    height: 85px;
}
.like .eyes {
    top: 13%;
}
.like .eyes::before,
.like .eyes::after {
    width: 18px;
    height: 5px;
    margin: 0px 12.5%;
    transform: rotate(-37.5deg);
    border-radius: 20px;
}
.like .eyes::after {
    transform: rotate(37.5deg);
}
.like .nose {
    top: 18%;
}
.like .mouth {
    top: 16.5%;
}
.like .tongue::before {
    height: 12px;
}
.like .tongue::after {
    height: 24px;
    -webkit-animation: movetongue 0.1s linear 0.35s infinite alternate forwards;
            animation: movetongue 0.1s linear 0.35s infinite alternate forwards;
}
.like .chin {
    top: 34%;
}
.tail {
    -webkit-animation: movetail 0.1s linear infinite alternate forwards;
            animation: movetail 0.1s linear infinite alternate forwards;
}

.dislike {
  background: #767aad;
}
.dislike .ears::before {
  transform: rotate(-50deg) translate(-7px, 2px);
}
.dislike .ears::after {
  transform: rotate(50deg) translate(7px, 2px);
}
.dislike .face::before {
  margin-top: 28px;
}
.dislike .face::after {
  height: 55px;
}
.dislike .eyes {
  top: 38%;
}
.dislike .eyes::before,
.dislike .eyes::after {
  width: 18px;
  height: 5px;
  margin: 0px 14.5%;
  transform: rotate(-37.5deg);
  border-radius: 20px;
}
.dislike .eyes::after {
  transform: rotate(37.5deg);
}
.dislike .teardrop {
  -webkit-animation: cry 0.1s ease-in 0.25s forwards;
          animation: cry 0.1s ease-in 0.25s forwards;
}
.dislike .nose {
  top: 44%;
}
.dislike .mouth {
  top: 42%;
}
.dislike .chin {
  top: 52%;
}
.dislike .tail {
  transform: rotate(0);
}

 

 

script

 

문제정보

 <script>
        // 문제 정보
        const quizInfo = [
            {
                infoType: "정보처리 기능사",
                infoTime: "2007년 5회",
                infoNumber: "20070501",
                infoQuestion: " 다음에 표시된 진리표가 나타내는 회로는?(단, 입력은 A, B이고 출력은 S(Sum)와 C(Carry) 이다.)<br><img style='width300px' src='../quiz/assets/img/Q1.jpg'>",
                infoChoice: {
                    1: "AND 회로",
                    2: "반가산기 회로",
                    3: "OR 회로",
                    4: "전가산기 회로",
                },
                infoAnswer: "2", 
                infoDesc: "입력이 A,B 2개 이고 출력이 S, C 2개 이므로 반가산기 입니다."
            },{
                infoType: "정보처리 기능사",
                infoTime: "2007년 5회",
                infoNumber: "20070502",
                infoQuestion: "JK 플립플롭에서 J=0, K=0이 입력되면 동작상태는 어떻게 되는가?",
                infoChoice: {
                    1: "변화 없음",
                    2: "Clear 상태",
                    3: "Set 상태",
                    4: "반전",
                },
                infoAnswer: "1", 
                infoDesc: "J=0, K=0 이므로 셋팅도 하지 말고 리셋도 하지 말라는 이야기 이므로 그냥 두라는 소리 입니다..변화없음이 답이되면, 기억, 불변 Qt등이 답이 될수 있습니다."
            },{
                infoType: "정보처리 기능사",
                infoTime: "2007년 5회",
                infoNumber: "20070503",
                infoQuestion: "EBCDIC 코드의 존(Zone) 코드는 몇 비트로 구성되어 있는가?",
                infoChoice: {
                    1: "8",
                    2: "7",
                    3: "6",
                    4: "4",
                },
                infoAnswer: "4", 
                infoDesc: "EBCDIC는 총 8비트로 구성되어 있으며 ASCII 7비트, BCD 6비트 입니다. 존코드비트 = 총코드비트 - 4 입니다."
            },{
                infoType: "정보처리 기능사",
                infoTime: "2007년 5회",
                infoNumber: "20070504",
                infoQuestion: "연산자의 기능과 거리가 먼 것은?",
                infoChoice: {
                    1: "주소 지정 기능",
                    2: "제어 기능",
                    3: "함수 연산 기능",
                    4: "입출력 기능",
                },
                infoAnswer: "1", 
                infoDesc: "연산자란 +, -, *, / 등 어떤 계산을 하라는 목적을 가지므로 주소와는 관련이 없습니다..명령어 = 명령어코드부 + 주소부로 구성 됩니다."
            },...
        ];

문제 안에 들어갈 정보들은 60문제이므로 너무 많아서 지금은 5문제 정도로 가져왔습니다.

quizInfo로 배열을 만들어 안에 정보들을 저장해줍니다.

infoType은 문제 유형, infoTime은 문제 회차, infoNumber는 문제 번호, infoQuestion은 문제, infoChoice는 선택지,

infoAnswer는 문제 답, infoDesc는 문제 해설입니다.

 

선택자

// 선택자
const quizWrap = document.querySelector(".quiz__wrap");

let quizScore = 0;

문제 정보들이 quiz__wrap에 들어가야 하므로 선택자로 quiz__wrap을 선택해줍니다.

점수를 초기값 0으로 설정해주었습니다.

 

 

문제 출력

// 문제 출력
const updateQuiz = () => {
const exam = [];

quizInfo.forEach((question, number) => {
    exam.push(`
    <div class="quiz">
        <div class="quiz__header">
            <h2 class="quiz__title">${question.infoType} ${question.infoTime}</h2>
        </div>
        <div class="quiz__main">
            <div class="quiz__question"><em>${number+1}</em>. ${question.infoQuestion}</div>
            <div class="quiz__view">
                <div class="dog_wrap">
                    <div class="true">정답입니다!</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__choice">
                <label for="choice1${number}">
                    <input type="radio" id="choice1${number}" name="choice${number}" class="select" value="1">
                    <span>${question.infoChoice[1]}</span>
                </label>
                <label for="choice2${number}">
                    <input type="radio" id="choice2${number}" name="choice${number}" class="select" value="2">
                    <span>${question.infoChoice[2]}</span>
                </label>
                <label for="choice3${number}">
                    <input type="radio"id="choice3${number}" name="choice${number}" class="select" value="3">
                    <span>${question.infoChoice[3]}</span>
                </label>
                <label for="choice4${number}">
                    <input type="radio"id="choice4${number}" name="choice${number}" class="select" value="4">
                    <span>${question.infoChoice[4]}</span>
                </label>
            </div>
            <div class="quiz__desc">정답은 <em>${question.infoAnswer}</em>번 입니다.<br>${question.infoDesc}</div>
        </div>
    </div>
    `);
});
 exam.push(`
                <div class="quiz__info">??점</div>
                <div class="quiz__check">정답 확인</div>
            `);
           quizWrap.innerHTML = exam.join("");

화살표 함수를 사용해 updateQuiz 를 출력시킵니다.

exam 배열을 선언하고 quizInfo가 다중이므로 forEach 메소드를 사용하여 quizInfo 배열 안에 있는 question과 number에 대해서 반복합니다.

push를 사용해서 quiz__wrap에 주석처리 해준 부분을 가져와서 exam.push로 배열 끝에 요소를 계속 추가시켜줍니다.

출력시키면 ,가 있으므로 없애주기 위해 배열 객체 매서드인 join를 사용해서 exam.join(' ')을 사용해서 요소를 추가시켜줍니다.

 

 

// 설명 숨기기
            document.querySelectorAll(".quiz__desc").forEach(el => el.style.display="none");            
        }
        updateQuiz();

문제를 풀기 전에 모든 문제의 해설을 모두 숨기기 위해 퀴즈 해설들을 forEach( )를 사용해서 스타일을 display = "none"을 입력해줍니다.

 

 

정답확인하기

// 정답 확인
        const answerQuiz = () => {
            const quizChoices = document.querySelectorAll(".quiz__choice");

            //사용자가 체크한 정답 == 문제 정답
            quizInfo.forEach((question, number) => {
                const userSelector = `input[name=choice${number}]:checked`;     //사용자가 체크하면 체크속성이 생김
                const quizSelectorWrap = quizChoices[number];
                const userAnswer =( quizSelectorWrap.querySelector(userSelector)|| {}).value;
                const dogWrap = quizWrap.querySelectorAll(".dog_wrap");

                if(userAnswer == question.infoAnswer){
                    console.log("정답");
                    dogWrap[number].classList.add("like");
                    quizScore++;
                } else {
                    console.log("오답");
                    dogWrap[number].classList.add("dislike");
                }
            });

            // 설명 보이기
            document.querySelectorAll(".quiz__desc").forEach(el => el.style.display="block");

            // 점수 보이기
            document.querySelector(".quiz__info").innerHTML = Math.ceil(quizScore / quizInfo.length*100) +"점";
           
        }

사용자가 선택한 정답이 문제의 정답과 일치하는지 확인하고, 그 결과에 따라 해당 문제의 개 quizWrap에 있는 개 이미지를 바꾸고, 사용자의 점수를 계산하는 함수입니다.

먼저, quizChoices라는 변수에 querySelectorAll 메소드를 사용하여 .quiz__choice 클래스를 가진 모든 엘리먼트를 가져옵니다.

forEach 메소드를 사용하여 quizInfo 배열에 있는 각 문제에 대해 다음 작업을 수행합니다.

userSelector 변수에 name 속성이 choice${number}인 라디오 버튼 중 체크된 항목의 선택자를 할당합니다.

quizSelectorWrap 변수에 quizChoices 배열에서 number 인덱스에 해당하는 요소를 할당합니다.

userAnswer 변수에 quizSelectorWrap 요소에서 userSelector 선택자를 사용하여 선택된 라디오 버튼의 value 값을 가져옵니다. 선택된 항목이 없는 경우 기본값으로 빈 객체 {}를 사용합니다.

dogWrap 변수에 quizWrap에서 .dog_wrap 클래스를 가진 모든 엘리먼트를 가져옵니다.

if 문을 사용하여 userAnswer 값과 question.infoAnswer 값이 일치하는지 비교합니다. 일치하는 경우 해당 문제의 개 이미지에 .like 클래스를 추가하고, quizScore 변수를 증가시킵니다. 일치하지 않는 경우 해당 문제의 개 이미지에 .dislike 클래스를 추가합니다.

마지막으로, forEach 메소드를 사용하여 모든 .quiz__desc 클래스를 가진 엘리먼트를 선택하고, style.display 속성을 "block"으로 설정하여 모든 문제의 설명을 표시합니다. 또한, 사용자의 점수를 계산하여 .quiz__info 클래스를 가진 엘리먼트에 출력합니다.

 

//정답 클릭
document.querySelector(".quiz__check").addEventListener("click",answerQuiz)

 

선택자를 통해 quiz__check를 클릭했을 때 addEventListener를 통해 answerQuiz가 출력될 수 있도록 해줍니다.

 

이렇게 하면 위와 같은 퀴즈 이펙트가 완성됩니다.

 

퀴즈 이펙트 1: https://zheldqmffhrm.tistory.com/28

 

자바스크립트 퀴즈 이펙트1

자바스크립트 퀴즈 이펙트 만들기 완성된 모습입니다. Quiz 정답 확인하기 유형 . 정답 확인하기 연변대비 1346zany@gmail.com 완성된 코드입니다. 설명 // 선택자 const quizWrap = document.querySelector(".quiz__wr

zheldqmffhrm.tistory.com

 

퀴즈 이펙트 2 :https://zheldqmffhrm.tistory.com/29

 

자바스크립트 퀴즈 이펙트2

자바스크립트 퀴즈 이펙트 만들기 완성된 모습입니다. Quiz 주관식 확인하기 유형 1 2 . 정답 확인하기 연변대비 설명 1346zany@gmail.com 완성된 코드입니다. 설명 // 선택자 const quizWrap = document.querySelec

zheldqmffhrm.tistory.com

 

퀴즈 이펙트 3 :https://zheldqmffhrm.tistory.com/35

 

자바스크립트 퀴즈 이펙트3

오늘은 위와 같은 퀴즈가 여러 개 있는 형식을 만들어 보겠습니다. Quiz 주관식 확인하기(여러문제) 유형 1 2 3 4 . 정답입니다! 틀렸습니다! 정답 확인하기 . 정답입니다! 틀렸습니다! 정답 확인하

zheldqmffhrm.tistory.com

퀴즈 이펙트 4 :https://zheldqmffhrm.tistory.com/34

 

자바스크립트 퀴즈 이펙트4

오늘은 위와 같은 선택지가 있는 퀴즈 이펙트를 만들어보도록 하겠습니다. Quiz 주관식 확인하기(여러문제) 유형 1 2 3 4 정답입니다! 틀렸습니다! 선, 색채, 공간, 수량 점, 선, 면 질감 시간, 수량,

zheldqmffhrm.tistory.com