Bomb Kirby Running

JAVASCRIPT

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

^. ̫ .^ 2023. 3. 27. 21:32

Whether you think you can or you think you can’t, you’re right.

Henry Ford

728x90

오늘은 저번처럼 객관식 문제가 여러 개 있는 유형이지만, 저번과 다르게 문제가 한문제 한문제 넘어가는 유형을 만들어 보겠습니다.

 

CSS

.quiz__answer .next {
    background-color: #9be8ff;
    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 .next:hover {
    background-color: #7cd5ff;

새로 추가된 CSS부분 입니다.

그동안 만들었던 정답확인 버튼과 다른 버튼이므로 quiz__answer. confirm 밑에 복사해서 .next를 만들어 주었습니다.

 

h4 {
    text-align: center;
    padding-top: 5px;
    font-family: 'Suncheon';
    font-size: 1.3vw;
    color: #fff;
    background-color: #80dbff;
}

그리고 강아지 위에 몇 문제가 남았는지 텍스트가 나오기 때문에 글씨와 여백 색을 설정하고 가운데 정렬을 해주었습니다.

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>퀴즈 이펙트06</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><a href="quizEffect05.html">5</a></li>
            <li class="active"><a href="quizEffect06.html">6</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">
                            <h4></h4>
                            <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="next">다음 문제</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>

지난번과 같은 객관식 유형이므로 주석처리를 푼 것을 빼면 5번과 동일합니다.

quiz__choice 부분은 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: ["AND 회로","반가산기 회로","OR 회로","전가산기 회로",],
        infoAnswer: "반가산기 회로", 
        infoDesc: "입력이 A,B 2개 이고 출력이 S, C 2개 이므로 반가산기 입니다."
    },{
        infoType: "정보처리 기능사",
        infoTime: "2007년 5회",
        infoNumber: "20070502",
        infoQuestion: "JK 플립플롭에서 J=0, K=0이 입력되면 동작상태는 어떻게 되는가?",
        infoChoice:["변화 없음","Clear 상태","Set 상태","반전",],
        infoAnswer: "변화 없음", 
        infoDesc: "J=0, K=0 이므로 셋팅도 하지 말고 리셋도 하지 말라는 이야기 이므로 그냥 두라는 소리 입니다..변화없음이 답이되면, 기억, 불변 Qt등이 답이 될수 있습니다."
    },{
        infoType: "정보처리 기능사",
        infoTime: "2007년 5회",
        infoNumber: "20070503",
        infoQuestion: "EBCDIC 코드의 존(Zone) 코드는 몇 비트로 구성되어 있는가?",
        infoChoice: ["8","7","6","4",],
        infoAnswer: "4", 
        infoDesc: "EBCDIC는 총 8비트로 구성되어 있으며 ASCII 7비트, BCD 6비트 입니다. 존코드비트 = 총코드비트 - 4 입니다."
    },{
        infoType: "정보처리 기능사",
        infoTime: "2007년 5회",
        infoNumber: "20070504",
        infoQuestion: "연산자의 기능과 거리가 먼 것은?",
        infoChoice: ["주소 지정 기능","제어 기능","함수 연산 기능","입출력 기능",],
        infoAnswer: "주소 지정 기능", 
        infoDesc: "연산자란 +, -, *, / 등 어떤 계산을 하라는 목적을 가지므로 주소와는 관련이 없습니다..명령어 = 명령어코드부 + 주소부로 구성 됩니다."
    },{
        infoType: "정보처리 기능사",
        infoTime: "2007년 5회",
        infoNumber: "20070505",
        infoQuestion: " 다음 중 불(Boolean) 대수의 정리로 옳지 않은 것은?",
        infoChoice: ["A+Ā=1","A+0=0","AĀ=0","A+A=A",],
        infoAnswer: "A + 0 = A", 
        infoDesc: "A + 0 = A 입니다."
    },{
        infoType: "정보처리 기능사",
        infoTime: "2007년 5회",
        infoNumber: "20070506",
        infoQuestion: "2진수 0110을 그레이 코드로 변환하면?",
        infoChoice: ["0010","0111","0101","1110",],
        infoAnswer: "0101", 
        infoDesc: "2진수를 그레이 코드로 변환시 앞에 숫자는 그냥 내리고 옆에 것을 더해서 내려주면 됩니다"
    }
];

이번엔 문제 6개 정도로만 추렸습니다.

 

선택자

//선택자
const quizWrap = document.querySelector(".quiz__wrap");
const quizTitle = quizWrap.querySelector(".quiz__title");
const quizQuestion = quizWrap.querySelector(".quiz__question")
const quizChoice = quizWrap.querySelector(".quiz__choice")
const dogWrap = quizWrap.querySelector(".dog_wrap");
const quizAnswer = quizWrap.querySelector(".quiz__answer");
const quizNext = quizWrap.querySelector(".quiz__answer .next");
const quizDesc = quizWrap.querySelector(".quiz__desc");
const quizNumcount= quizWrap.querySelector(".dog_wrap h4");
const quizCheck = quizWrap.querySelector(".quiz__check span");

let quizCount = 0;
let quizScore = 0;

선택자로 각각의 요소들을 선택해줍니다.

그리고 quizCount와 quizScore의 초깃값을 0으로 설정해줍니다.

 

문제출력

 //문제출력
const updateQuiz = (index) => {

    let typeTag = `
        <span>${quizInfo[index].infoType}</span>
        <em>${quizInfo[index].infoTime}</em>
    `;
    let questionTag = `
        <em>${index+1}</em>.
        <span>${quizInfo[index].infoQuestion}</span>
    `;
    let choiceTag = `
        <label for="choice1">
            <input type="radio" id="choice1" name="choice" class="select" value="1">
            <span>${quizInfo[index].infoChoice[0]}</span>
        </label>
        <label for="choice2">
            <input type="radio" id="choice2" name="choice" class="select" value="2">
            <span>${quizInfo[index].infoChoice[1]}</span>
        </label>
        <label for="choice3">
            <input type="radio"id="choice3" name="choice" class="select" value="3">
            <span>${quizInfo[index].infoChoice[2]}</span>
        </label>
        <label for="choice4">
            <input type="radio"id="choice4" name="choice" class="select" value="4">
            <span>${quizInfo[index].infoChoice[3]}</span>
        </label>
    `;
    let descTag = `
        정답은 ${quizInfo[index].infoAnswer}입니다.<br>
        ${quizInfo[index].infoDesc}
    `;
    let CountTag = `
        <div>${quizInfo.length}문제 중 ${quizInfo.length-index}문제 남았습니다.</div>
    `;

    quizTitle.innerHTML = typeTag;
    quizQuestion.innerHTML = questionTag;
    quizChoice.innerHTML = choiceTag;
    quizDesc.innerHTML = descTag;
    quizNumcount.innerHTML = CountTag;

익명함수의 화살표 함수를 통해 각각의 태그를 달아줍니다.

updateQuiz 함수는 index 매개변수를 받아서 해당 인덱스의 퀴즈 정보를 HTML 태그로 만들어 웹 페이지 상에 출력하는 역할을 합니다.

typeTag는 quizInfo에서 index번째 퀴즈의 유형과 시간 정보를 담습니다.

questionTag는 quizInfo에서 index번째 퀴즈의 질문 내용을 담습니다

choiceTag는 quizInfo에서 index번째 퀴즈의 보기 정보를 담습니다.

descTag는 quizInfo에서 index번째 퀴즈의 정답과 설명 정보를 담습니다.

CountTag는 quizInfo의 개수와 개수에서 index값을 빼서 전체 문제 수와 남은 문제 수를 담습니다.

 

보기 선택자

    // 보기 선택자
    const quizChoiceSpan = quizWrap.querySelectorAll(".quiz__choice span");
    const quizChoiceInput = quizWrap.querySelectorAll(".quiz__choice input");

    // quizChoiceSpan.forEach((span,num) => {
    //     span.setAttribute("onclick", "choiceSelected(this)");
    // });
    for(let i=0; i<quizChoiceSpan.length; i++){
    quizChoiceSpan[i].setAttribute("onclick", "choiceSelected(this)");
    //quizChoiceInput[i].disabled = "true";
    }

선택자로 보기에서 텍스트들을 담고 있는 span과 input박스를 선택해줍니다.

for문으로 setAttribute()를 통해 span에 onclick 이벤트를 할당하고 onclick될 때 choiceSelected()함수를 호출합니다.

 

다음 버튼, 해설 숨기기

//다음 버튼, 해설 숨기기
    quizAnswer.style.display = "none";
    quizDesc.style.display = "none";
};

updateQuiz(quizCount);

quizAnswer와 quizDesc에 스타일로 display:none;을 해주어 다음으로 넘어가는 버튼과 해설을 숨깁니다.

 

객관식 선택 했을 때

//객관식 선택
function choiceSelected(answer){
    let userAnswer = answer.textContent;        //사용자 정답
    let currentAnswer = quizInfo[quizCount].infoAnswer;     //문제 정답

    if(userAnswer == currentAnswer){
        console.log("정답입니다.")
        dogWrap.classList.add("like");
        dogWrap.classList.remove("dislike");
        quizScore++;
    } else {
        console.log("오답입니다.")
        dogWrap.classList.add("dislike");
        dogWrap.classList.remove("like");
    }

변수를 통해 사용자가 입력한 정답과 문제의 정답을 가져오고,

if문을 통해 사용자가 선택한 답과 문제의 정답을 비교합니다.

정답인 경우 강아지가 웃는 얼굴, 오답일 경우 울상짓는 얼굴이 되도록 설정합니다.

 

다음 버튼, 해설 나타나기

//다음 버튼, 해설 나타나기
    quizAnswer.style.display = "block";
    quizDesc.style.display = "block";

둘 다 style을 display: block을 주어 답을 선택하고 난 뒤 다음으로 넘어가는 버튼과 해설이 보이도록 해줍니다.

 

//맞힌개수 틀린개수 점수
        if(quizInfo.length - quizCount == 1){
            alert(quizScore+"개 맞았고,"+(quizInfo.length - quizScore)+"개 틀렸습니다."+"점수는"+ Math.ceil((quizScore / quizInfo.length) * 100) + "점입니다.");
            quizCheck.innerHTML = quizScore;
        }
    }

 

if문을 이용해  quizInfo의 개수에서 quizCount를 뺐을때 1이 될때(마지막 문제를 풀었을 때)

alert(알림창)이 나타나 quizScore로 몇개 맞았는지, quizInfo의 개수에서 quizScore를 빼서 몇개 틀렸는지 알 수 있게 설정하고 Math.ceil로 계산하여 점수를 구해서 같이 나타나게 해줍니다.

 

 

 // 정답 확인
    quizNext.addEventListener("click", () => {
        quizCount++;
        updateQuiz(quizCount);

        dogWrap.classList.remove("like","dislike");

    });

다음 버튼을 클릭했을 때 quizCount 값을 1 증가시켜 다음 문제를 가져오는 updateQuiz 함수를 호출합니다.

그리고 문제와 보기, 설명 등이 업데이트되도록 합니다.

그리고 강아지 이미지에 적용된 클래스인 like와 dislike를 제거하여, 다음 문제에서 새로운 정답 여부를 표시할 수 있도록 준비합니다.

 

퀴즈 이펙트 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

퀴즈 이펙트 5 : https://zheldqmffhrm.tistory.com/48

 

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

오늘은 저번에 만든 퀴즈 이펙트 4번처럼 객관식 유형을 선택할 수 있는 퀴즈 유형을 만들겁니다. 4번을 이용해서 오늘은 더 많은 문제를 선택할 수 있는 유형을 만들어보도록 하겠습니다. 코드

zheldqmffhrm.tistory.com