예제/퀴즈 이펙트

퀴즈 이펙트_여러 문제를 한번에 풀 수 있도록 만들어 봅시다!

아라라_ 2023. 3. 14. 13:26

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

Frederick Philips Brooks
Mythical Man-Month 저자
728x90

오늘 은 퀴즈 이펙트를 한페이지에 여러개를 넣어 한번에 풀 수 있도록 하려고 합니다.

 

 

html

<div class="quiz">
    <div class="quiz__header">
        <h2 class="quiz__title"><span></span> <em></em></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="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>
    <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>

html을 위와 같이 세개를 만들어 줍니다. 

이는 한페이지에 3문제를 한번에 볼 수있도록 하는것으로 똑같은 이펙트를 html로 구현합니다.

 

 

선택자

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 quizAnswerInput = quizWrap.querySelectorAll(".quiz__answer .input");          //사용자 정답
const dogwrap = quizWrap.querySelectorAll(".dog__wrap");

선택자를 선택하여 변수에 넣어 값을 받을 준비를 합니다.

 

 

문제 정보

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

문제를 배열안에 객체로 문제 정보를 넣습니다.

 

 

문제 정보 출력(forEach()으로)

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;
});

forEach()에서 처음 배열이름은 반복하고자하는 대상의 이름으로 대상을 지정하고 그 안에 값이 들어값니다.

하지만 이때 함수에 el(엘리먼트(요소)) 없다면 인텍스를 엘리 먼트로 봅니다.

만약 그냥 요소를 출력하게 되면 그 출력된 값안에 모든 그 요소가 들어있습니다.

 

 

답과 해설 숨기기

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

위와 같은 원리로 숨기기위해 답과 해설을 지정한 변수에 style.display으로 none을 줍니다.

 

innerHTML과 textContent의 차이

textContent는 텍스트만 출력, innerHTML은 HTML의 속성까지 적용하여 출력합니다.

 

 

정답확인

quizAnswerConfirm.forEach(function(btn, num){
    btn.addEventListener("click", function(){
        // 사용자 정답
        const userAnswer = quizAnswerInput[num].value; // 트림은 사이에 있는 공백을 못잡는다
        quizAnswerConfirm[num].style.display = "none";   // 정답 학인 버튼 숨김
        quizAnswerInput[num].style.display = "none";     // 인풋 박스 숨김
        quizAnswerResult[num].style.display = "block";   // 정답 보기
        quizDesc[num].style.display = "block";           // 해설 보기

        // 사용자 정답 == 문제 정답
        if(userAnswer == quizInfo[num].infoAnswer){
            dogwrap[num].classList.add("like");
            dogwrap[num].classList.remove("dislike");
        } else {
            dogwrap[num].classList.add("dislike");
            dogwrap[num].classList.remove("like");
        };
    });
});

 

우선 forEach()을 사용하는데 이때 클릭하는 의미로 btn과 인덱스 번호를 의미하는 num을 매개변수로 줍니다.

그 후 버튼을 눌러 함수를 실행 할 수있도록 add EventListener를 주어 클릭이라는 이벤트를 줍니다.

이때 userAnswer라는 변수를 주어 userAnswer를  quizAnswerInput[num].value에서 값을 찾아서 가져올수 있도록 합니다.

이 변수로 if else문으로 정답이면 강아지가 웃고 오답이면 강아지가 웁니다.

정답이든 아니든 무조건 정답과 해설이 나오고 버튼과 text박스를 숨깁니다.

이를  forEach()를 사용했기때문에 문제 3개를 반복 할 수있습니다.