오늘은 퀴즈 이펙트 세 번째를 작업해보겠습니다!

저번에는 정답인지 오답인지 판별하는 효과였다면 이번엔 여러 개의 주관식을 확인해보는 효과를 해보겠습니다!

두 번째에 했던 효과와 거의 흡사하지만 이번엔 여러 개가 있어 다중선택자를 사용해보겠습니다.

 

자바스크립트 퀴즈 이펙트(세 번째) 만들기

영역 지정해주기

<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="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__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="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__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="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__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>

두 번째와 했던 것과는 다르게 문제가 3개이므로 quiz 영역을 복사해 3개로 만들어줍니다.

그리고 이번에 추가된 것은 맞췄을 시, 정답 혹은 오답인지 애니메이션 효과를 주기 위해 dog__wrap 밑부분에 영역을 넣어줍니다.

선택자 만들기

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

어제와 같이 변수를 지정해주고 document.querySelector( )를 사용해 선택자를 만들어줍니다. 그리고 괄호 안에 각 내용에 맞는 이름들을 적어둡니다. 전에 했던 것과 동일하므로 재활용하고, 추가로 넣어준 내용만 선택자를 만들어줍니다.

 

여기서 두 번째와 다른 점은 선택자인 querySelector에 All이라는 것이 붙었습니다.

그럼 이게 무엇인지 알아봐야겠죠?

 

querySelectorAll?

querySelectorAll은 JavaScript에서 DOM(Document Object Model)을 조작할 때 사용하는 메서드 중 하나입니다.

 

querySelectorAll 메서드는 CSS 선택자(CSS selector)를 사용하여, 문서 내의 여러 요소들을 선택할 수 있습니다. 이 메서드는 선택자와 일치하는 모든 요소를 NodeList 객체로 반환합니다.

문제 정보 입력하기

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

여러 개의 문제 정보를 입력할 때는 배열과 객체를 사용해 데이터를 저장해줍니다.

quizInfo라는 변수에 배열을 만들어주고, 객체를 활용해 각 문제의 번호와 질문, 답, 해설등을 입력해줍니다.

 

문제 출력하기

//시험 종목 + 시험 날짜
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].infoQeustion;
quizQuestion[1].textContent = quizInfo[1].infoQeustion;
quizQuestion[2].textContent = quizInfo[2].infoQeustion;

이번엔 시험 종목과 시험 날짜를 합쳐 출력해보겠습니다.

배열 안에 들었으니 quizTitle[0]을 사용하고 infoType과 infoTime 사이에  + " " +를 추가해 같이 출력되게 해줍니다.

문제가 총 3문제 있으니 위의 코드처럼 배열 인덱스값을 입력해줍니다.

 

하지만 이렇게 적으면 코드가 지저분해지고 가독성이 떨어지기 때문에 

for문과 forEach()를 사용해 작업해보겠습니다.

 

문제 출력하기_for문

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].infoQeustion;
    quizAnswerResult[i].textContent = quizInfo[i].infoAnswer;
    quizDesc[i].textContent = quizInfo[i].infoDesc;
}

for문을 통해 i값을 배열의 갯수만큼 반복해주고 증가시켜준다음, 배열 안 인덱스 값에 i를 넣어주면 위의 복잡한 코드를 줄일 수 있습니다. 이것을 forEach()로 바꿔볼까요?

 

문제 출력하기_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].infoQeustion;
    quizAnswerResult[i].textContent = quizInfo[i].infoAnswer;
    quizDesc[i].textContent = quizInfo[i].infoDesc;
});

forEach()를 통해 이렇게도 쓸 수 있습니다.

 

✔forEach() 공식!

배열명.forEach(function(요소명){실행문});

 

정답&해설 숨기기

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";

style.display = "none"을 사용해 정답과 해설을 숨겨줍니다.

위에서 한 작업처럼 이 코드도 for문과 forEach()로 바꿔줄 수 있습니다.

 

정답&해설 숨기기_for문과 forEach()

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

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

 

정답 확인하기

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");
        } else {
            dogWrap[num].classList.add("dislike");
        }
    });
});

정답 또한 forEach()로 바로 작업해줍니다. 

버튼을 눌렀을 때 실행되는 함수를 입력해줍니다.

 

또한, 정답을 입력했을 때, 확인 버튼 숨김/인풋 박스 숨김/정답과 해설을 보여주게 작업해줍니다.

style.display = "none" <--- 숨기기

style.display = "none" <--- 보이기

 

완성된 화면과 페이지

 

https://yeodaseul4355.github.io/web2023/javascirpt/quiz/quizEffect03.html

 

도움이 되셨다면~~ 많은 공감과 댓글 부탁드려용 ^^!

퀴즈 이펙트의 다른 유형 보러가기

퀴즈 이펙트 1: https://duektmf34.tistory.com/33

퀴즈 이펙트 2: https://duektmf34.tistory.com/34

퀴즈 이펙트 4: https://duektmf34.tistory.com/47

퀴즈 이펙트 5: https://duektmf34.tistory.com/57

728x90
반응형
다쭐◠‿◠