지난 포스팅에서는 여러개의 문제를 불러와 나열하는 형식이었는데요.
오늘은 답을 맞추면 넘어가는 형식으로 해보겠습니다!
HTML
<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">
<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" 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>
<div class="quiz__answer">
<button class="next">다음 문제</button>
</div>
<div class="quiz__desc"></div>
</div>
</div>
</div>
</main>
퀴즈 만들기 4번과 동일한 형식이지만 객관식 부분을 주석 처리해주었습니다. 한 문제를 풀면 다음 문제로 넘어가야 하는 방식이기에 한 문제 한문제 모두에 객관식을 넣기보다는 자바스크립트에서 태그를 작성해 작업하기 위해 주석처리를 해주었습니다.
Script
const quizInfo = [
{
infoType : "정보처리기능사",
infoTime : "2008년 2회",
infoNumber : "20080201",
infoQuestion : "다음 논리회로에서 출력 f의 값은? <img style ='width:200px' src='../assets/data img/image_01.jpg' alt='image_01.jpg'>",
infoChoice : ["-1", "0", "1/2", "1"],
infoAnswer : "1",
infoDesc : "1 AND 1 = 1<br>1 AND 0 = 0<br>1 OR 0 = 1이므로 최종 출력은 1그리고 게이트 문제에서 출력은 무조건 0 아니면 1입니다. 1/2 또는 -1, -2 등은 답이 될수 없습니다."
}]
퀴즈에 대한 정보는 quizInfo라는 변수로 선언해주고 배열 속의 개게 형식으로 데이터를 저장해주었습니다.
//선택자
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 quizNext = quizWrap.querySelector(".quiz__answer .next");
const quizDesc = quizWrap.querySelector(".quiz__desc");
const quizAnswer = quizWrap.querySelector(".quiz__answer");
const dogHeader = quizWrap.querySelector(".quiz__main h3")
let quizCount = 0;
let quizScore = 0;
선택자 부분입니다. 각각의 선택자를 변수에 저장해주었고 quizCount는 quizinfo의 인덱스 값이며 quizScore는 점수를 위한 변수입니다.
const updateQuiz = (index) =>{
let dogHeaderTag = `
${quizInfo.length - quizCount} 문제 남았습니다.
`;
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" value="1">
<span>${quizInfo[index].infoChoice[0]}</span>
</label>
<label for="choice2">
<input type="radio" id="choice2" name="choice" value="2">
<span>${quizInfo[index].infoChoice[1]}</span>
</label>
<label for="choice3">
<input type="radio" id="choice3" name="choice" value="3">
<span>${quizInfo[index].infoChoice[2]}</span>
</label>
<label for="choice4">
<input type="radio" id="choice4" name="choice" value="4">
<span>${quizInfo[index].infoChoice[3]}</span>
</label>
`;
let descTag = `
정답은 ${quizInfo[index].infoAnswer}입니다.
${quizInfo[index].infoDesc}
`;
quizTitle.innerHTML = typeTag;
quizQuestion.innerHTML = questionTag;
quizChoice.innerHTML = choiceTag;
quizDesc.innerHTML = descTag;
dogHeader.innerHTML = dogHeaderTag;
👉 updateQuiz : 이 변수는 퀴즈 정보를 지속해서 업데이트 해주기 위한 변수입니다. 이 코드에서는 매개변수로 활용 되고 있습니다.
👉 let dogHeaderTag = `${quizInfo.length - quizCount} 문제 남았습니다.`
퀴즈 인포라는 배열의 갯수 (length) 에서 퀴즈 카운트를 빼준 뒤, 뒤편에 문자열을 붙여주는 코드입니다.
👉 let typeTag = `
<span>${quizInfo[index].infoType}</span>
<em>${quizInfo[index].infoTime}</em>
`;
퀴즈 인포라는 변수 내에서 index값을 불러오기 위한 코드입니다. index값 중에서도 infoType과 infoTime을 불러옵니다.
👉 let questionTag = `
<em>${index+1}</em>.
<span>${quizInfo[index].infoQuestion}</span>
`;
문제 번호를 불로오고, 퀴즈 인포의 질문을 불러오는 코드입니다.
👉let ChoiceTag 객관식 목록임과 동시에 퀴즈 인포의 객관식 선택지 데이터를 불러오는 코드입니다.
👉let descTag 문제에 대한 부연설명과 답을 가져오는 코드입니다.
//보기 선택자
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.disabled = "true";
}
// 다음 버튼 숨기기 해설
quizAnswer.style.display = "none";
quizDesc.style.display = "none";
for 반복문을 사용하여 quizChoiceSpan 요소 배열을 반복합니다.
i 변수는 현재 반복하는 요소의 인덱스를 나타냅니다.
반복문의 각 단계에서, quizChoiceSpan[i] 요소의 onclick 속성을 "choiceSelected(this)"로 설정합니다. 이렇게 함으로써, 사용자가 해당 요소를 클릭할 때 choiceSelected() 함수가 호출되고, 요소 자체가 함수의 인자로 전달됩니다.
//객관식 선택
function choiceSelected(answer){
let userAnswer = answer.textContent; //사용자 정답
let currentAnswer = quizInfo[quizCount].infoAnswer; // 문제 정답
if(userAnswer == currentAnswer){
console.log("정답");
dogWrap.classList.add("like");
quizScore++;
}else{
console.log("오답");
dogWrap.classList.add("dislike");
}
//다음 버튼, 해설 나타나기
quizAnswer.style.display = "block";
quizDesc.style.display = "block";
if(quizInfo.length - quizCount == 1){
alert(quizScore + "개 맞았습니다." + Math.ceil((quizScore / quizInfo.length) * 100) + "점 입니다.");
};
};
//정답 확인
quizNext.addEventListener("click", () => {
quizCount++;
updateQuiz(quizCount);
dogWrap.classList.remove("like", "dislike");
});
👉choiceSelected(answer)
함수는 객관식 답변이 선택될 때마다 호출됩니다.
함수는 사용자가 선택한 답변을 userAnswer 변수에 저장하고, 현재 문제의 정답을 currentAnswer 변수에 저장합니다.
userAnswer와 currentAnswer를 비교하여, 사용자가 선택한 답변이 정답인지 여부를 판별합니다.
👉사용자가 정답을 선택한 경우, quizScore를 증가시키고, dogWrap 요소에 like 클래스를 추가합니다.
* like는 강아지의 환한 표정입니다.
그렇지 않은 경우, dogWrap 요소에 dislike 클래스를 추가합니다.
* dislike는 슬픈 표정입니다.
quizAnswer와 quizDesc 요소를 보이도록 설정하여, 정답과 해설이 표시됩니다.
quizCount 변수를 증가시키고, 다음 문제를 보여주는 updateQuiz(quizCount) 함수를 호출합니다.
dogWrap 요소에서 like와 dislike 클래스를 보이지 않도록 가려줍니다.