이번에는 슬라이드 형식의 객관식 질문으로 작업하고 있습니다!

JavaScript 퀴즈 효과 만들기(5부)
지역 지정
<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>
<h4></h4>
<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 class="quiz__info">??점</div>
<div class="quiz__check"><span>?</span>개</div>
</div>
</div>
</div>
</main>
<!-- //main -->
<footer id="footer">
<a href="http://duektmf34.m/mailto:[email protected]">[email protected]</a>
</footer>
<!-- //footer -->
Quiz Effect No.1의 구조를 거의 파악했습니다. 5 관련. 다른 하나는 desc 아래에 퀴즈__정보(점수)와 퀴즈__체크(정답 수)를 하는 것입니다. 그리고 퀴즈__질문 아래에 h4를 입력하여 질문 아래에 몇 개의 질문이 남아 있는지 말하십시오.
문제 정보 생성
// 문제 정보
const quizInfo = (
{
infoType: "정보처리 기능사",
infoTime: "2007년 1회",
infoNumber: "20070101",
infoQuestion: "8bit를 1word로 이용하는 컴퓨터에서 op-code를 3bit 사용하면 인스트럭션을 몇 개 사용할 수 있는가?",
infoChoice: ("4","6","8","16"),
infoAnswer: "8",
infoDesc: "<br>op-code가 3비트란 말은 명령어부가 3비트라는 이야기 입니다.<br>3비트로 표현가능한 명령어(인스트럭션)수는 2의 3승개(2^3)는 8입니다."
},{
infoType: "정보처리 기능사",
infoTime: "2007년 1회",
infoNumber: "20070102",
infoQuestion: "중앙처리장치의 제어 부분에 의해서 해독되어 현재 실행중인 명령어를 기억하는 레지스터는?",
infoChoice: ("PC(Program Counter)","IR(Instruction Register)","MAR(Memory Address Register)","MBR(Memory Buffer Register)"),
infoAnswer: "IR(Instruction Register)",
infoDesc: "<br>명령어를 기억하는 레지스터는 IR(Instruction Register, 명령어레지스터)입니다."
},{
infoType: "정보처리 기능사",
infoTime: "2007년 1회",
infoNumber: "20070103",
infoQuestion: "번지(address)로 지정된 저장위치(storage locations)의 내용이 실제 번지가 되는 주소지정번지는?",
infoChoice: ("간접지정번지","완전지정번지","절대지정번지","상대지정번지"),
infoAnswer: "간접지정번지",
infoDesc: "<br>번지가 실제 내용의 번지가 되므로 메모리 참조회수 2회, 간접주소지정방식 입니다."
},{
infoType: "정보처리 기능사",
infoTime: "2007년 1회",
infoNumber: "20070104",
infoQuestion: "전가산기(full adder)는 어떤 회로로 구성되는가?",
infoChoice: ("반가산기 1개와 OR 게이트로 구성된다.","반가산기 1개와 AND 게이트로 구성된다.","반가산기 2개와 OR 게이트로 구성된다.","반가산기 2개와 AND 게이트로 구성된다."),
infoAnswer: "반가산기 2개와 OR 게이트로 구성된다.",
infoDesc: "<br>전가산기는 반가산기 2개 + OR 게이트 1개로 구성 됩니다."
},{
infoType: "정보처리 기능사",
infoTime: "2007년 1회",
infoNumber: "20070105",
infoQuestion: "명령어(Instructions) 형식에서 첫 번째 바이트의 기능이 아닌 것은?",
infoChoice: ("자료의 주소지정 기능","제어 기능","자료전달 기능","함수연산 기능"),
infoAnswer: "자료의 주소지정 기능",
infoDesc: "<br>명령어 = 명령어 코드부 + 명령어 주소부로 구성됩니다.<br> 첫번째 바이트이므로 명령과 관련된 내용이 기록되는데,주소 지정은 주소부에서 합니다. "
},{
infoType: "정보처리 기능사",
infoTime: "2007년 1회",
infoNumber: "20070106",
infoQuestion: "컴퓨터시스템의 중앙처리장치를 구성하는 하나의 회로로서 산술 및 논리연산을 수행하는 장치는?<br><img style="width:300px" src="">",
infoChoice: ("Arithmetic Logic Unit","Memory Unit","I/O Unit","Associative Memory Unit"),
infoAnswer: "Arithmetic Logic Unit",
infoDesc: "<br>Arithmetic: 산술 / Logic: 논리 / Unit: 장치"
}
);
QuizInfo에 배열을 만들고 질문 정보를 입력합니다. 6개 정도 추가하면 됩니다. 지난번과 다른 점은 view를 infoChoice에 객체로 저장했다면 이번에는 배열로 저장한다는 것입니다.
또한 infoAnswer는 숫자가 아닌 정답인 문자열도 삽입합니다.
선택기 만들기
// 선택자
const quizWrap = document.querySelector(".quiz__wrap");
const quizMainH4 = quizWrap.querySelector(".quiz__main h4");
const quizTitle = quizWrap.querySelector(".quiz__title");
const quizChoice = quizWrap.querySelector(".quiz__choice");
const quizQuestion = quizWrap.querySelector(".quiz__question");
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");
const quizCheck = quizWrap.querySelector(".quiz__check span");
let quizCount = 0;
let quizScore = 0;
셀렉터는 이전과 거의 동일합니다.
나는 방금 퀴즈메인H4라는 셀렉터를 추가했다. 이 부분은 총 문제가 몇 개 남았는지 알려주는 선택기입니다.
또한 퀴즈체크라는 선택기를 사용하여 얼마나 많은 합계가 일치했는지 알려주는 퀴즈__체크 범위 부분에 선택기를 만듭니다.
문제 인쇄
const updateQuiz = (index) => {
let typeTag = `
<span>${quizInfo(index).infoType}</sapn>
<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}입니다.<br>
${quizInfo(index).infoDesc}
`;
let h4Tag = `
총 ${quizInfo.length - index}문제 남았습니다.
`;
quizTitle.innerHTML = typeTag;
quizQuestion.innerHTML = questionTag;
quizChoice.innerHTML = choiceTag;
quizDesc.innerHTML = descTag;
quizMainH4.innerHTML = h4Tag;
// 보기 선택자
const quizChoiceSpan = quizWrap.querySelectorAll(".quiz__choice span");
const quizChoiceInput = quizWrap.querySelectorAll(".quiz__choice input");
// forEach()
// quizChoiceSpan.forEach((span, num) => {
// span.setAttribute("onclick", "choiceSelected(this)");
// });
// for문
for(let i=0; i<quizChoiceSpan.length; i++){
quizChoiceSpan(i).setAttribute("onclick", "choiceSelected(this)");
// quizChoiceInput(i).disabled = "true";
}
// 다음 버튼, 해설 숨기기
quizAnswer.style.display = "none";
quizDesc.style.display = "none";
};
updateQuiz(quizCount);
이 코드는 updateQuiz라는 함수를 정의하고 호출합니다.
updateQuiz 함수는 index라는 매개변수를 사용합니다.
updateQuiz 함수는 퀴즈 정보 배열에서 색인화된 퀴즈 정보를 가져와 퀴즈 제목, 질문, 옵션, 정답 및 주석을 HTML 요소에 생성하고 innerHTML 속성을 통해 요소에 삽입합니다.
또한 선택한 보기의 스타일을 변경하고 다음 버튼과 주석을 숨깁니다.
마지막으로 우리는 함수를 호출하고 퀴즈카운트 변수의 값을 인덱스로 전달합니다.
지난 번에 푸시와 조인을 사용했다면 이번에는 태그라는 변수를 만들어서 출력했습니다. 퀴즈효과는 5번과 6번 두 가지가 공통적으로 사용되는 방법이니 잘 이해하고 알아두자!
forEach()를 사용한 출력
// forEach()
quizChoiceSpan.forEach((span, num) => {
span.setAttribute("onclick", "choiceSelected(this)");
});
for 문으로 출력
// for문
for(let i=0; i<quizChoiceSpan.length; i++){
quizChoiceSpan(i).setAttribute("onclick", "choiceSelected(this)");
// quizChoiceInput(i).disabled = "true";
}
setAttribute?
setAttribute 메소드는 HTML 요소의 속성 값을 설정합니다. 이 방법을 사용하여 특정 HTML 요소의 속성 값을 변경할 수 있습니다.
setAttribute 메소드는 두 개의 매개변수를 허용합니다. 첫 번째 매개변수는 변경할 속성의 이름이고 두 번째 매개변수는 해당 속성에 할당할 값입니다.
객관식 선택한 값 가져오기
// 객관식 선택
function choiceSelected(answer){
let userAnswer = answer.textContent; // 사용자 정답
let currentAnswer = quizInfo(quizCount).infoAnswer; //문제 정답
if(userAnswer == currentAnswer){
dogWrap.classList.add("like");
dogWrap.classList.remove("dislike");
quizScore++;
} else {
dogWrap.classList.add("dislike");
dogWrap.classList.remove("like");
}
// 다음 버튼, 해설 나타나기
quizAnswer.style.display = "block";
quizDesc.style.display = "block";
if(quizInfo.length - quizCount == 1){
document.querySelector(".quiz__info").innerHTML = Math.ceil((quizScore / quizInfo.length) * 100) + "점";
quizCheck.innerHTML = quizScore;
}
};
이 코드는 choiceSelected 함수를 정의합니다.
choiceSelected 함수는 사용자가 선택한 보기(답변 매개변수)를 가져와 해당 보기의 내용을 userAnswer 변수에 할당하고 현재 질문에 대한 정답을 currentAnswer 변수에 할당합니다.
그런 다음 userAnswer와 currentAnswer를 비교하여 사용자의 선택이 정답과 일치하는지 확인합니다. 일치하는 경우 dogWrap이라는 요소에 like 클래스를 추가하고 싫어요 클래스를 제거한 다음quisscore 변수를 1씩 증가시킵니다.
일치하지 않으면 Like 클래스를 제거하고 Dislike 클래스를 추가합니다.
그런 다음, 다음 버튼과 댓글을 표시하기 위해 퀴즈앤서 및 퀴즈데스크 요소의 디스플레이 속성을 “차단”으로 설정합니다.
마지막으로 이것이 퀴즈의 마지막 질문이면 사용자의 총점을 퀴즈 점수로 계산하여 화면에 표시하고 퀴즈 점수도 QuizCheck 요소에 출력합니다.
정답을 출력
// 정답 확인
quizNext.addEventListener("click", () => {
quizCount++;
updateQuiz(quizCount);
dogWrap.classList.remove("like", "dislike");
});
이 코드는 QuizNext 버튼을 클릭할 때 실행되는 콜백 함수를 정의합니다.
이 콜백 함수는 퀴즈카운트 변수를 1씩 증가시키고 화면에 다음 질문을 표시하기 위해 updateQuiz 함수를 호출합니다.
그리고 dogWrap 요소에서 like 및 dislike 클래스를 모두 제거하여 이전 문제에서 추가된 스타일을 초기화합니다. 이런 식으로 새로운 문제에서 강아지 그림에 대한 반응을 재설정할 수 있습니다.