오늘은 퀴즈 이펙트 세 번째를 작업해보겠습니다!
저번에는 정답인지 오답인지 판별하는 효과였다면 이번엔 여러 개의 주관식을 확인해보는 효과를 해보겠습니다!
두 번째에 했던 효과와 거의 흡사하지만 이번엔 여러 개가 있어 다중선택자를 사용해보겠습니다.
자바스크립트 퀴즈 이펙트(세 번째) 만들기
영역 지정해주기
<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