WEB/JAVASCRIPT

[javascript] QUIZ : 객관식 문제 만들기

aimee418 2023. 3. 18. 12:42

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

- Frederick Philips Brooks
Mythical Man-Month 저자
728x90
반응형

QUIZ  : 객관식 문제 만들기

객관식 퀴즈를 만들어 보려고 합니다.(웹디자인 기능사 문제 입니다)

 

순서.

✈. 객관식 퀴즈 화면을 만들고

✈. 답을 체크하면,

✈. 정답과 해설이 나오고,

✈. 정답이면 강아지가 웃고, 

✈. 오답이면 강아지가 우는 

퀴즈를 만들어 보겠습니다!

 

 

✈객관식 퀴즈  화면 만들기

1. 먼저 보여져야 할 화면을 디자인 합니다.
2. HTML으로 구조를 작성해 줍니다.
3. CSS로 디자인을 적용해 주고(컬러와 글씨체 등) 
4. JAVASCRIPT로 퀴즈의 정보를 담은 스크립트를 넣어줍니다.    

 

 

 

 

 

 

 

 

 

 

 

🏁. HTML :  구조를 작성해 줍니다. 

 <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" value="1">
                            <span class="choice"></span>
                        </label>
                        <label for="choice2">
                            <input type="radio" id="choice2" name="choice" value="2">
                            <span class="choice"></span>
                        </label>
                        <label for="choice3">
                            <input type="radio" id="choice3" name="choice" value="3">
                            <span class="choice"></span>
                        </label>
                        <label for="choice4">
                            <input type="radio" id="choice4" name="choice" value="4">
                            <span class="choice"></span>
                        </label>
                    </div>
                    <div class="quiz__answer">
                        <button class="confirm" >정답확인하기</button>              
                    </div>
                    <div class="quiz__desc">설명</div>
                </div>


           

            </div>

        </div>

    </main>
    <!-- //main -->

🏁. CSS :  디자인을 적용해 줍니다. 

/* header */
#header {
    background-color: #d3d3d3;
    color: #fff;
    padding: 10px;
    position: fixed;
    left: 0;
    top: 0;
    width: 100%;
    display: flex;
    justify-content: space-between;

}
#header::before {
    content: '';
    border: 4px ridge #ccc;
    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: #666;
} 




/* footer */
#footer {
    position: fixed;
    left: 0;
    bottom: 0;
    width: 100%;
    background-color: #d3d3d3;
    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 #333;
    position: absolute;
    left: 5px;
    top: 5px;
    width: calc(100% - 16px);
    height: calc(100% - 12px);
    
}
#main {
    padding: 100px 0;
}
/* quiz__wrap */
.quiz__wrap {
    display: flex;
    justify-content: center;
    flex-wrap: wrap;
}
.quiz__wrap .quiz{
    width: 500px;
    background-color: #fff;
    border: 8px ridge #d3d3d3;
    margin: 10px;
}
.quiz__header{}
.quiz__title{
    background-color: #d3d3d3;
    border: 3px ridge #ccc;
    border-bottom-width: 6px;
    padding: 5px;
    font-family: 'DungGeunMo';
    font-size: 16px;
    color: #ffffff;
    text-align: center;
}
.quiz__main{}
.quiz__question {
    color: #3b3b3b;
    padding: 20px;
    font-size: 24px;
    font-family: 'NanumSquareNeo';
    font-weight: bold;
    line-height: 1.5;
    border-bottom: 6px ridge #ccc;
}
.quiz__question em {
    color : #333;
}

🏴. 공통CSS

/* reset css */
@import url('https://webfontworld.github.io/neodgm/NeoDunggeunmo.css');
@import url('https://webfontworld.github.io/DungGeunMo/DungGeunMo.css');
@import url('https://webfontworld.github.io/PyeongChang/PyeongChang.css');
@import url('https://webfontworld.github.io/NanumSquareNeo/NanumSquareNeo.css');
* {
    margin: 0;
    padding: 0;
    box-sizing: border-box;
}
*, *::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;
}

🏴. JAVASCRIPT 퀴즈의 정보를 담은 문제의 정보를 넣어줍니다

    <script>
        // 선택자
        const quizWrap = document.querySelector(".quiz__wrap");
        const quizTitle = quizWrap.querySelector(".quiz__title");
        const quizQuestion= quizWrap.querySelector(".quiz__question");
        const quizChoice = quizWrap.querySelectorAll(".quiz__choice span");
        const quizSelect = quizWrap.querySelectorAll(".quiz__choice input");
        
        // 문제 정보
        const quizInfo = [
            {
                infoType: "웹디자인 기능사",
                infoTime: "2016년 4회",
                infoNumber: "1",
                infoQuestion: "다음 중 디자인의 기본 요소들로 옳은 것은?",
                infoChoice: ["선, 색채, 공간, 수량", "점, 선, 면, 질감", "시간, 수량, 구조, 공간", "면, 구조, 공간, 수량"],
                infoAnswer: "2",
                infoDesc: "디자인의 기본 요소에는 점, 선, 면, 질감이 있습니다."
            }
        ];
        // 문제 출력
        function updateQuiz(){
            quizTitle.innerHTML = quizInfo[0].infoType +" "+ quizInfo[0].infoTime;
            quizQuestion.innerHTML = "<em>"+quizInfo[0].infoNumber+"</em>."+ quizInfo[0].infoQuestion;
            quizDesc.innerHTML = quizInfo[0].infoDesc;
            for(let i=0; i<4; i++){
                quizChoice[i].textContent = quizInfo[0].infoChoice[i];
            }
            // 해설 숨기기
            quizDesc.style.display = "no
        }
        //문제 출력
        updateQuiz();

 

 

 

✈답 체크하기

 CSS에 정답을 체크했을 때 input에 체크되도록 설정합니다.

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

🏴. CSS

.quiz__choice {
  padding: 20px;
  border-bottom: 6px ridge #cacaca;
  font-family: 'NanumSquareNeo';
}
.quiz__choice label {
    display: flex;
}
.quiz__choice label input {
    /* position: absolute; */
    /* left: -9999px; */
    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;
    margin-right: 15px;
    border-radius: 50%;
    background-color: #fff;
    box-shadow: inset 0 0 0 4px #6fa30b;
    transition: all 0.2s;
    flex-shrink: 0;
    /* flex 일정이상 작아지지 않도록 */
}
.quiz__check {
    position: fixed;
    right: 20px;
    bottom: 80px;
    width: 130px;
    height: 130px;
    text-align: center;
    line-height: 130px;
    border-radius: 50%;
    z-index: 1000;
    background: #222;
    color: #fff;
    font-family: 'NanumSquareNeo';
    cursor: pointer;
}
.quiz__check a:hover {
}
.quiz__choice label input:checked + span {
    background-color: #f5ffe7;
}
.quiz__choice label input:checked + span::before {
  box-shadow: inset 0 0 0 8px #6fa30b;
}

🏴. JAVASCRIPT 체크박스 스크립트 설정하기

// 선택자
const quizChoice = quizWrap.querySelectorAll(".quiz__choice span");
const quizSelect = quizWrap.querySelectorAll(".quiz__choice input");
const quizConfirm = quizWrap.querySelector(".quiz__answer .confirm");

// 정답 확인
function answerQuiz(){      
	// 사용자가 선택한 인풋박스(checked) == 문제 정답(quizInfo[0].infoAnswer)
	for(let i=0; i<quizChoice.length; i++){
        if(quizSelect[i].checked == true){  //사용자가 보기를 체크한 상태
        	}
    }
}
// 정답 클릭
quizConfirm.addEventListener("click", answerQuiz);

 

 

 

 

 

 

 

 

 

 

 

 

 

✈정답과 해설 나오기

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

🏴. 

      // 정답 확인
        function answerQuiz(){      
            // 사용자가 선택한 인풋박스(checked) == 문제 정답(quizInfo[0].infoAnswer)
            for(let i=0; i<quizChoice.length; i++){
                if(quizSelect[i].checked == true){  //사용자가 보기를 체크한 상태
                    if(quizSelect[i].value == quizInfo[0].infoAnswer){
                    //    alert("정답입니다.");
                        dogWrap.classList.add("like");
                    } else {
                    //    alert("오답입니다.")
                        dogWrap.classList.add("dislike");
                    }
                }
            }
            //해설 보이기
            quizDesc.style.display = "block";
            //정답 숨기기
            quizAnswer.style.display = "none";
        }
        // 정답 클릭
        quizConfirm.addEventListener("click", answerQuiz);
        //문제 출력
        updateQuiz();

 

✈정답일 때 강아지 웃기

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

정답일 때 class명 like를 스크립트로 추가시켜 줍니다.

🏁. script

        // 정답 확인
        function answerQuiz(){      
            // 사용자가 선택한 인풋박스(checked) == 문제 정답(quizInfo[0].infoAnswer)
            for(let i=0; i<quizChoice.length; i++){
                if(quizSelect[i].checked == true){  //사용자가 보기를 체크한 상태
                    if(quizSelect[i].value == quizInfo[0].infoAnswer){
                    //    alert("정답입니다.");
                        dogWrap.classList.add("like");
                    }

🏁. class= 'like' css

.like {  background: #ffdcd0;}
.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;animation: movetongue 0.1s linear 0.35s infinite alternate forwards;}
.like .chin { top: 34%;}

 

✈오답일 때 강아지 울기

오답일 때 class명 like를 스크립트로 추가시켜 줍니다.

🏁. script

        // 정답 확인
        function answerQuiz(){      
            // 사용자가 선택한 인풋박스(checked) == 문제 정답(quizInfo[0].infoAnswer)
            for(let i=0; i<quizChoice.length; i++){
                if(quizSelect[i].checked == true){  //사용자가 보기를 체크한 상태
                    if(quizSelect[i].value == quizInfo[0].infoAnswer){
                    //    alert("정답입니다.");
                        dogWrap.classList.add("like");
                    } else {
                    //    alert("오답입니다.")
                        dogWrap.classList.add("dislike");
                    }
                }
            }

🏁. class= 'dislike' css

.dislike {  background: #9879d0;}
.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 {  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);}