퀴즈 사이트 ( 3 )
주관식 문제를 3개를 풀 수 있도록 만들어 보겠습니다.
[ 분신술이개! ]
VSCode
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>퀴즈 이펙트03</title>
<link rel="stylesheet" href="css/reset.css">
<link rel="stylesheet" href="css/quiz.css">
</head>
<body>
<header id="header">
<h1><a href="../javascript14.html">Quiz <em>주관식 확인하기</em></a></h1>
<ul>
<li><a href="quizEffect01.html">1</a></li>
<li><a href="quizEffect02.html">2</a></li>
<li class="active"><a href="quizEffect03.html">3</a></li>
<li><a href="quizEffect04.html">4</a></li>
</ul>
</header>
우측 상단에 1~4번 문제를 확인하는 버튼쪽 입니다.
class="active"를 써줘서 해당 페이지에 있을 시 버튼이 활성화 돼있다는 표시를 줬습니다.
<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>
우리 개가 분신술을 사용했기 때문에 코드도 분신술을 써서 길어 보입니다.
한마리 코드만 보면 그리 길지 않습니다.
이 코드 역시 1~2번째 글과 다르지 않습니다.
<script>
//선택자
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"); //개 표정
//문제 정보
const quizInfo = [
{
infoType: "정보처리 기능사",
infoTime: "2012년 2회",
infoNumber : "1",
infoQuestion: "주파수분할 다중화 방식에서 각 채널간 간섭을 막기 위해서 일종의 완충지역 역할을 하는 것은 무엇이라고 하는가?",
infoAnswer: "가드밴드",
infoDesc: "가드밴드(Guard Band)는 주파수분할 다중화 방식에서 각 채널간 간섭을 막기 위해서 일종의 완충지역 역할이다."
},{
infoType: "정보처리 기능사",
infoTime: "2012년 2회",
infoNumber : "2",
infoQuestion: "사용자의 명령으로 시스템이 수행되고 그에 따른 결과를 나타내 주는 대화식 운영체제는 무엇인가?",
infoAnswer: "UNIX",
infoDesc: "UNIX는 사용자의 명령으로 시스템이 수행되고 그에 따른 결과를 나타내 주는 대화식 운영체제이다."
},{
infoType: "정보처리 기능사",
infoTime: "2012년 2회",
infoNumber : "3",
infoQuestion: "프로세스들이 서로 다른 프로세스가 차지하고 있는 자원을 무한정 기다려 시스템이 멈춘 것처럼 보이는 상태를 무엇이라고 하는가?",
infoAnswer: "교착상태",
infoDesc: "교착상태는 2개 이상의 프로세스들이 서로 다른 프로세스가 차지하고 있는 자원을 무한정 기다려 시스템이 멈춘 것처럼 보이는 현상이다."
}
];
//문제 출력
quizInfo.forEach(function(e, i){
quizTitle[i].innerHTML = quizInfo[i].infoType +" "+ quizInfo[1].infoTime;
quizQuestionNum[i].textContent = quizInfo[i].infoNumber;
quizQuestion[i].textContent = quizInfo[i].infoQuestion;
quizAnswerResult[i].textContent = quizInfo[i].infoAnswer;
quizDesc[i].textContent = quizInfo[i].infoDesc;
});
quizInfo.forEach((el, 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;
quizAnswerResult[num].style.display = "none";
quizDesc[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");
}
});
});
</script>
대망의 스크립트 부분입니다.
//선택자 는 문제와 제목, 정답, 해설같은 정보들이 들어갈 자리를 const변수에 저장해주는 것 입니다. 이 변수를 사용해
innerHTML, textContent 메서드를 이용하여 정보를 자리에 불러 올 수있습니다.
//문제정보 는 //선택자 자리에 들어갈 정보들 입니다.
//문제출력 은 //선택자 자리에 //문제정보 를 넣어 출력하는 방법입니다.
//사용자정보 는 forEach문을 사용해 //문제정보의 배열을 불러오고 사용자가 정답을 입력하면 정답인지 오답인지 구별하기 if문을 사용했습니다.
forEach문
여기서 핵심은 여러번 써야 하는 for문들을 forEach를 사용해 코드 내용을 줄였습니다.
//사용자 정답
//1단(수작업)
//문제 종류 + 문제 시간
// quizTitle[0].innerHTML = quizInfo[0].infoType +" "+ quizInfo[1].infoTime;
// quizTitle[1].innerHTML = quizInfo[0].infoType +" "+ quizInfo[1].infoTime;
// quizTitle[2].innerHTML = quizInfo[0].infoType +" "+ quizInfo[1].infoTime;
//문제 번호
// quizQuestionNum[0].textContent = quizInfo[0].infoNumber;
// quizQuestionNum[1].textContent = quizInfo[1].infoNumber;
// quizQuestionNum[2].textContent = quizInfo[2].infoNumber;
//문제 질문
// quizQuestion[0].textContent = quizInfo[0].infoQuestion;
// quizQuestion[1].textContent = quizInfo[1].infoQuestion;
// quizQuestion[2].textContent = quizInfo[2].infoQuestion;
//2단(for문)
// for(let i=0; i<quizInfo.length; i++){
// quizTitle[i].innerHTML = quizInfo[i].infoType +" "+ quizInfo[1].infoTime;
// quizQuestionNum[i].textContent = quizInfo[i].infoNumber;
// quizQuestion[i].textContent = quizInfo[i].infoQuestion;
// quizAnswerResult[i].textContent = quizInfo[i].infoAnswer;
// quizDesc[i].textContent = quizInfo[i].infoDesc;
// quizAnswerResult[i].style.display = "none";
// quizDesc[i].style.display = "none";
// }
// 문제 출력
//3단(forEach문)
quizInfo.forEach(function(e, i){
quizTitle[i].innerHTML = quizInfo[i].infoType +" "+ quizInfo[1].infoTime;
quizQuestionNum[i].textContent = quizInfo[i].infoNumber;
quizQuestion[i].textContent = quizInfo[i].infoQuestion;
quizAnswerResult[i].textContent = quizInfo[i].infoAnswer;
quizDesc[i].textContent = quizInfo[i].infoDesc;
// quizAnswerResult[i].style.display = "none";
// quizDesc[i].style.display = "none";
});
//정답 숨기기
//1단(수작업)
// 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";
//2단(forEach문)
quizInfo.forEach((el, i) => {
quizAnswerResult[i].style.display = "none";
quizDesc[i].style.display = "none";
});
처음엔 수작업으로 일일이 작업하고, 그 반복되는 작업을 for문으로 줄여보지만 여전히 깁니다.
그걸 바로 forEach문으로 완전단축 해버리는 겁니다.
여기서 처음 쓰는 메서드가 있는데 그건 바로,
querySelectorAll(), innerHTML() 입니다. gtp의 힘을 빌려 설명해보자면,
querySelectorAll()은 JavaScript에서 DOM(Document Object Model)에서 원하는 요소를 선택하기 위한 메서드 중 하나입니다.
이 메서드는 CSS 선택자를 사용하여 원하는 요소를 선택하고 NodeList 객체를 반환합니다. NodeList는 선택된 모든 요소의 목록이며, 배열과 비슷하지만 배열이 아닙니다.
innerHTML은 JavaScript에서 DOM(Document Object Model) 요소의 내용을 읽거나 수정하기 위한 속성 중 하나입니다. 이 속성은 해당 요소의 HTML 내용을 반환하거나 변경할 수 있습니다.
[ 오늘은 울개 😢 ]