Leeyanggoo
[JS] 퀴즈 이펙트 만들기4!! 객관식 문제는 어떻게 만들까? 본문
이젠 주관식 퀴즈를 넘어 퀴즈의 정석이라 할 수 있는 객관식 퀴즈를 만들어 볼 차례입니다!
객관식은 정답이 될 수 있는 여러 개의 보기를 보여줘야 하고 또 선택함에 따라 바뀌는 코드를 짜야 하기 때문에,
주관식보다 더 복잡한 코드를 짜야 한다고 볼 수 있습니다.
객체와 배열 그리고 for문
//문제
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<quizChoice.length; i++){
quizChoice[i].textContent = quizInfo[0].infoChoice[i];
}
//해설 숨기기
quizDesc.style.display = "none";
}
//정답 확인
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){
dogWrap.classList.add("like");
} else {
dogWrap.classList.add("dislike");
}
}
}
//해설 보이기
quizDesc.style.display = "block";
//정답 확인 숨기기
quizAnswer.style.display = "none";
}
quizConfirm.addEventListener("click", answerQuiz);//정답 클릭
updateQuiz(); //문제 출력
문제의 정보를 담은 quizInfo가 어떤 식으로 이뤄져 있는지 먼저 살펴볼까요?
"const quizInfo = [ "로 시작하는 걸 보니 배열로 시작해서 "{ }" 객체 안에 각각 문제가 담을 정보마다 키와 값으로 짜여있는 걸 볼 수 있습니다.
아직은 문제가 하나지만 만약 여러 개로 늘어난다면 quizInfo의 배열 하나하나는 문제 하나씩이 되겠죠?
객관식은 보기가 여러 개이기 때문에 quizInfo 속의 "infoChoice"를 자세히 살펴봐야 합니다.
quizInfo가 배열 - 객체 그리고 infoChoice가 다시 배열로 보기를 담고 있기 때문에 순차적으로 불러와야 합니다.
1. quizInfo[0]로 문제를 부르게 되고, 첫 번째 문제 객체 속의 infoChoice이기 때문에 객체 호출을 붙여서
2, 3. quizInfo[0].infoChoice가 됩니다.
4. 여기서 infoChoice의 첫 번째 보기를 부른다면 보기는 배열 안에 들어있으므로 "quizInfo[0].infoChoice[0]"가 될 거예요!
우리는 여기서 더 나아가 4개의 보기를 모두 불러와야 하기 때문에 for문을 이용해야 합니다!
<div class="quiz__choice">
<label for="choice1">
<input type="radio" id="choice1" name="choice" value="1">
<span></span>
</label>
<label for="choice2">
<input type="radio" id="choice2" name="choice" value="2">
<span></span>
</label>
<label for="choice3">
<input type="radio" id="choice3" name="choice" value="3">
<span></span>
</label>
<label for="choice4">
<input type="radio" id="choice4" name="choice" value="4">
<span></span>
</label>
</div>
먼저 보기가 4개기 때문에 HTML에서도 "quiz__choice"에서 4개의 <label> 태그를 만들고 "querySelectAll()"을 이용해 모두 선택해줬습니다.
infoChoice의 모든 보기를 불러오기 위해선 배열의 길이를 불러올 수 있는 속성인 ".length"를 이용해야겠죠!?
따라서 입력된 for문은 이렇게 나오게 됩니다.
for문의 i가 0부터 점점 증가할 때 "quiz__choice"의 <span>의 개수만큼(quizChoice.length) 증가합니다.
따라서 quizChoice의 [i]는 보기의 개수를 의미하게 되고, 위에서 infoChoice를 불러오는 방식을 이용하게 되면,
"quizInfo[0].infoChoice[i]"라는 식으로 보기 텍스트가 들어가게(.textContent) 됩니다.
😮💨 이전 포스팅 보러 가기
😮💨 이번 예제 보러 가기
😮💨 codepen design by David López