완성 화면
코드 보기 / JAVASCRIPT
//선택자
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 quizAnswer = quizWrap.querySelector(".quiz__answer");
const quizNext = quizWrap.querySelector(".quiz__answer .next");
const quizDesc = quizWrap.querySelector(".quiz__desc");
let questionCount = 0;
let quizCount = 0;
let quizScore = 0;
//문제출력
const updateQuiz = (index) => {
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;
//객관식 보기 선택자
const quizChoiceSpan = quizWrap.querySelectorAll(".quiz__choice span");
const quizChoiceInput = quizWrap.querySelectorAll(".quiz__choice input");
// quizChoiceSpan.forEach((span, num)=>{
// span.setAttribute("onclick", "choiceSelected(this)");
// });
for(i=0; i<quizChoiceSpan.length; i++){
quizChoiceSpan[i].setAttribute("onclick","choiceSelected(this)");
quizChoiceInput.disabled = "true";
}
//다음 버튼 숨기기
quizAnswer.style.display = "none";
quizDesc.style.display = "none";
};
updateQuiz(quizCount);
function choiceSelected(answer){
let userAnswer = answer.textContent; //사용자 정답
let currentAnswer = quizInfo[quizCount].infoAnswer; //문제 정답
if(userAnswer == currentAnswer) {
console.log("O");
dogWrap.classList.add("like");
} else {
console.log("X");
dogWrap.classList.add("dislike");
}
//나타내기
quizAnswer.style.display = "block";
quizDesc.style.display = "block";
}
//정답 확인
quizNext.addEventListener("click",()=>{
quizCount++;
updateQuiz(quizCount);
dogWrap.classList.remove("like","dislike")
});
const updateQuiz = (index) => { ...... }
: updateQuiz 함수는 'index' 라는 매개변수를 받아들인다.
이 index는 quizInfo 배열에서 몇 번째 퀴즈 정보를 가져올지를 결정하는 인덱스 값이다.
let TypeTag = `
<span>${quizInfo[index].infoType}</span>
<em>${quizInfo[index].infoTime}</em>
`;
: TypeTag 변수는 HTML 태그 문자열을 저장하는 변수이다.
이 문자열은 quizInfo 배열에서 index에 해당하는 퀴즈 정보의 종류와 시간을 표시하는 HTML 태그 문자열이다.
let QuestionTag = `
<span>${index+1}</span>
<em>${quizInfo[index].infoQuestion}</em>
`;
:QuestionTag 변수는 또 다른 HTML 태그 문자열을 저장하는 변수이다.
이 문자열은 quizInfo 배열에서 index에 해당하는 퀴즈 정보의 문제를 표시하는 HTML 태그 문자열이다.
index+1은 배열의 키가 0으로 시작한다는 것을 고려하여 실제 문제 번호와 맞추기 위해 1을 더해준 것이다.
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>
`;
: choiceTag 변수는 또 다른 HTML 태그 문자열을 저장하는 변수이다.
이 문자열은 quizInfo 배열에서 index에 해당하는 퀴즈 정보의 선택지를 표시하는 HTML 태그 문자열이다.
for 속성은 해당 선택지를 클릭하면 id 속성이 일치하는 input 요소가 선택되도록 한다.
let DescTag = `
정답은 ${quizInfo[index].infoAnswer}.
${quizInfo[index].infoDesc}
`;
: updateQuiz 함수 외부에서 호출되는 코드로, updateQuiz 함수에서 반환된 HTML 태그 문자열을 실제 문서에 삽입하는 역할을 한다.
DescTag 변수는 해당 문제의 정답과 설명을 담은 HTML 태그 문자열을 저장한다.
quizTitle.innerHTML = TypeTag;
quizQuestion.innerHTML = QuestionTag;
quizChoice.innerHTML = ChoiceTag;
quizDesc.innerHTML = DescTag;
: quizTitle, quizQuestion, quizChoice, quizDesc는 문서에서 해당 요소의 ID를 가진 HTML 태그들을 가리키는 변수이다.
이 변수들에 innerHTML 속성을 이용해서 updateQuiz 함수에서 반환된 태그 문자열을 삽입하면, 해당 페이지에서는 동적으로 생성된 퀴즈가 보여지게 된다.
즉, quizTitle에는 퀴즈의 종류와 시간을 표시하는 태그 문자열이, quizQuestion에는 문제를 표시하는 태그 문자열이, quizChoice에는 선택지를 표시하는 태그 문자열이, quizDesc에는 정답과 설명을 표시하는 태그 문자열이 삽입되게 된다.
const quizChoiceSpan = quizWrap.querySelectorAll(".quiz__choice span");
const quizChoiceInput = quizWrap.querySelectorAll(".quiz__choice input");
: 첫째 quizWrap 요소에서 quiz_choice span과 quiz__choice input을 모두 선택해서 각각 quizChoiceSpan과 quizChoiceInput 변수에 저장한다.
for (i = 0; i < quizChoiceSpan.length; i++) {
quizChoiceSpan[i].setAttribute("onclick", "choiceSelected(this)");
quizChoiceInput.disabled = "true";
}
: 반복문을 이용해 quizChoiceSpan의 모든 요소에 onclick 요소를 추가한다
setAttribute 메서드는 HTML 요소에 속성을 추가하거나 수정하는 메서드이다.
여기에서는 onclick 속성을 추가하고, 값으로 choiceSelected(this)를 할당한다.
this는 현재 클릭한 요소를 가리킨다.
따라서 choiceSelected 함수를 호출할 때, 해당 선택지에 대한 정보를 인자로 전달할 수 있다.
또한 quizChoiceInput.disabled = "true";는 선택지에 대응하는 input 요소를 비활성화 한다.
이는 선택지를 클릭했을 때, 선택지를 다시 클릭할 수 없도록 만드는 역할을 한다.
quizAnswer.style.display = "none";
quizDeac.style.display = "none";
};
updateQuiz(quizCount);
:quizAnswer와 quizDesc 요소를 화면에서 숨긴다.
style 속성의 display 값으로 none을 지정함으로써 해당 요소를 화면에서 숨길 수 있다.
이 구문을 추가함으로써 초기 상태에서는 정답과 설명이 보이지 않는다.
updateQuiz 함수를 호출하고 quizCount 값을 전달한다.
quizCount는 현재 문제의 인덱스를 저장하는 변수이며, 페이지가 로드 되었을 때 첫 번째 문제가 화면에 나타나게 된다.
function choiceSelected(answer){
let userAnswer = answer.textContent; // 사용자가 선택한 답변을 가져옴.
let currentAnswer = quizInfo[quizCount].infoAnswer; // 현재 문제의 정답을 가져옵니다.
if(userAnswer == currentAnswer) {
console.log("O");
dogWrap.classList.add("like");
} else {
console.log("X");
dogWrap.classList.add("dislike");
}
quizAnswer.style.display = "block";
quizDesc.style.display = "block";
: answer 매개변수는 사용자가 선택한 답변을 나타내는 HTML 요소이다.
answer.textContent를 사용하여 사용자가 선택한 답변의 내용을 가져와 userAnswer 변수에 저장한다.
그리고 quizInfo[quizCount].infoAnswer를 사용하여 현재 문제의 정답을 가져와 currentAnswer 변수에 저장한다.
그 다음 if문을 사용하여 unswerAnswe와 currentAnswer를 비교한다.
만약 두 값이 같다면 "O"를 콘솔에 출력하고 강아지 이미지에 "like" 클래스를 추가한다.
두 값이 다르다면 "X"를 콘솔에 출력하고 강아지 이미지에 "dislike" 클래스를 추가한다.
quizAnswer와 quizDesc 요소의 display 요소의 속성을 block으로 변경하여 정답과 해설을 보여준다.