“ 당신이 6개월 이상 한 번도 보지 않은 코드는 다른 사람이 다시 만드는 게 훨씬 더 나을 수 있다. ”
자바스크립트 퀴즈(Quiz) 사이트 만들기
이번에 만들어 본 퀴즈 사이트는 CBT 유형입니다.
전에 올린 퀴즈 사이트(7-1)에서 조금 보충한 내용들을 정리해보겠습니다.
퀴즈 사이트 추가 코드
<div class="cbt__start">
<div class="cbt__modal1">
<h2>💛기능사 시험 화이팅💛</h2>
<div class="cbt__choice">
<select name="cbtTime" id="cbtTime" onchange="changeSelect(this)">
<option value="gineungsaJC2005_02">정보처리기능사 2005년 2회</option>
<option value="gineungsaJC2005_04">정보처리기능사 2005년 4회</option>
<option value="gineungsaJC2005_05">정보처리기능사 2005년 5회</option>
<option value="gineungsaJC2006_01">정보처리기능사 2006년 1회</option>
<option value="gineungsaJC2006_02">정보처리기능사 2006년 2회</option>
<option value="gineungsaJC2006_03">정보처리기능사 2006년 3회</option>
<option value="gineungsaJC2006_05">정보처리기능사 2006년 5회</option>
<option value="gineungsaJC2007_01">정보처리기능사 2007년 1회</option>
<option value="gineungsaJC2007_02">정보처리기능사 2007년 2회</option>
<option value="gineungsaJC2007_04">정보처리기능사 2007년 4회</option>
<option value="gineungsaJC2007_05">정보처리기능사 2007년 5회</option>
<option value="gineungsaJC2008_01">정보처리기능사 2008년 1회</option>
<option value="gineungsaJC2008_02">정보처리기능사 2008년 2회</option>
<option value="gineungsaJC2008_04">정보처리기능사 2008년 4회</option>
<option value="gineungsaJC2008_05">정보처리기능사 2008년 5회</option>
<option value="gineungsaJC2009_01">정보처리기능사 2009년 1회</option>
<option value="gineungsaJC2009_05">정보처리기능사 2009년 5회</option>
<option value="gineungsaJC2010_02">정보처리기능사 2010년 2회</option>
<option value="gineungsaJC2010_05">정보처리기능사 2010년 5회</option>
<option value="gineungsaJC2011_01">정보처리기능사 2011년 1회</option>
<option value="gineungsaJC2011_02">정보처리기능사 2011년 2회</option>
<option value="gineungsaJC2011_04">정보처리기능사 2011년 4회</option>
<option value="gineungsaJC2011_05">정보처리기능사 2011년 5회</option>
</select>
<select name="cbtTime" id="cbtTime" onchange="changeSelect(this)">
<option value="gineungsaWD2009_05">웹디자인기능사 2009년 5회</option>
<option value="gineungsaWD2010_01">웹디자인기능사 2010년 1회</option>
<option value="gineungsaWD2010_02">웹디자인기능사 2010년 2회</option>
<option value="gineungsaWD2010_04">웹디자인기능사 2010년 4회</option>
<option value="gineungsaWD2010_05">웹디자인기능사 2010년 5회</option>
<option value="gineungsaWD2011_01">웹디자인기능사 2011년 1회</option>
<option value="gineungsaWD2011_02">웹디자인기능사 2011년 2회</option>
<option value="gineungsaWD2011_04">웹디자인기능사 2011년 4회</option>
<option value="gineungsaWD2011_05">웹디자인기능사 2011년 5회</option>
<option value="gineungsaWD2012_02">웹디자인기능사 2012년 2회</option>
<option value="gineungsaWD2012_04">웹디자인기능사 2012년 4회</option>
<option value="gineungsaWD2012_05">웹디자인기능사 2012년 5회</option>
<option value="gineungsaWD2013_02">웹디자인기능사 2013년 2회</option>
<option value="gineungsaWD2013_04">웹디자인기능사 2013년 4회</option>
<option value="gineungsaWD2013_05">웹디자인기능사 2013년 5회</option>
<option value="gineungsaWD2014_01">웹디자인기능사 2014년 1회</option>
<option value="gineungsaWD2014_04">웹디자인기능사 2014년 4회</option>
<option value="gineungsaWD2014_05">웹디자인기능사 2014년 5회</option>
<option value="gineungsaWD2015_01">웹디자인기능사 2015년 1회</option>
<option value="gineungsaWD2015_03">웹디자인기능사 2015년 3회</option>
<option value="gineungsaWD2015_04">웹디자인기능사 2015년 4회</option>
<option value="gineungsaWD2015_05">웹디자인기능사 2015년 5회</option>
<option value="gineungsaWD2016_01">웹디자인기능사 2016년 1회</option>
<option value="gineungsaWD2016_04">웹디자인기능사 2016년 4회</option>
</select>
</div>
<div class="cbt__view">
당신의 이름은 <input type="text" class="name"> 입니다.<br>
당신은 <span class="subject">웹디자인 기능사시험</span>을 선택했습니다.
</div>
<!-- <button class="minimal">시작하기</button> -->
<button class="cbt__start__btn">시작하기</button>
</div>
</div>
div 태그를 사용하여 시험자의 이름과 선택한 시험 항목을 보여주는 영역을 만들었습니다. 이름은 input 태그를 사용하여 입력할 수 있도록 하였습니다.
그리고 button 태그를 사용하여 "시작하기" 버튼을 만들어 시험을 시작할 수 있도록 하였습니다. 이 버튼을 클릭했을 때 시험을 시작하는 동작을 구현할 수 있습니다.
const cbtViewSubject = document.querySelector(".cbt__view .subject");
const cbtHeader = document.querySelector(".cbt__header h2");
const cbtStartBtn = document.querySelector(".cbt__start__btn");
const cbtStart = document.querySelector(".cbt__start");
const cbtTime = document.querySelector(".cbt__time");
const cbtEndScore = document.querySelector(".cbt__end__score")
const cbtName = document.querySelector(".cbt__name");
const yourName = document.querySelector(".cbt__view .name");
새로 만들어준 선택자 입니다.
let questionTime = "";
let questionTimeRemain = "3600";
let quizScore = 0; // 현재 점수
//시작하기
const startQuiz = () => {
cbtStart.classList.add("hide"); //모달창 제거
//시간 설정
questionTime = setInterval(reduceTime, 1000);
//입력 이름 나오게
cbtName.innerHTML = `${yourName.value}`
}
첫 번째 줄에서는 questionTime 변수를 빈 문자열로 초기화하고, questionTimeRemain 변수를 "3600"으로 초기화합니다. quizScore 변수는 0으로 초기화됩니다.
다음으로 startQuiz 함수가 정의됩니다. 이 함수는 퀴즈를 시작하는 역할을 합니다.
cbtStart 요소의 classList에 hide 클래스를 추가하여 모달 창을 숨기는 것으로 시작합니다.
그 다음, setInterval 함수를 사용하여 reduceTime 함수를 1초마다 실행하도록 questionTime 변수를 설정합니다. 이 함수는 시험 시간을 감소시키는 역할을 합니다.
마지막으로, cbtName 요소의 내용을 입력한 이름으로 변경합니다. 이렇게 함으로써 이름이 퀴즈 화면에 나타나게 됩니다.
//설명 없는거 제거
document.querySelectorAll(".cbt__question__desc").forEach(desc => {
if(desc.innerText === "undefined"){
desc.classList.add("hide");
}
});
//이미지가 없는거 제거-
document.querySelectorAll(".cbt__question__img").forEach(img => {
let src = img.querySelector("img").src;
if(src.includes("undefined")){
img.classList.add("hide");
}
});
//점수 표시
document.querySelector(".cbt__submit").addEventListener("click", () => {
document.querySelector(".cbt__end__score").innerHTML = Math.ceil((quizScore / questionLength) * 100);
});
- 첫 번째 블록은 "cbt__question__desc" 클래스를 가진 요소들을 선택하고, 이들의 텍스트 내용이 "undefined"인 경우 "hide" 클래스를 추가하여 화면에서 해당 요소를 숨기는 기능입니다.
- 두 번째 블록은 "cbt__question__img" 클래스를 가진 요소들을 선택하고, 이들의 자식 요소 중 "img" 태그의 "src" 속성값이 "undefined"인 경우 "hide" 클래스를 추가하여 화면에서 해당 요소를 숨기는 기능입니다.
- 마지막 블록은 "cbt__submit" 클래스를 가진 버튼이 클릭될 때, 시험 점수를 계산하여 "cbt__end__score" 클래스를 가진 요소에 해당 점수를 표시하는 기능입니다.
위 코드를 통해 CBT 페이지에서 문제 내용이나 이미지가 없는 경우, 해당 요소를 화면에서 숨기고, 시험을 마치면 점수를 표시하는 기능을 구현할 수 있습니다.
//시간 설정
const reduceTime = () => {
questionTimeRemain--;
if(questionTimeRemain == 0) endQuiz();
cbtTime.innerText = displayTime();
}
//시간 표시
const displayTime = () => {
if(questionTimeRemain <= 0){
return "0분 00초"; //종료 의미, 결과 의미
} else {
let minutes = Math.floor(questionTimeRemain / 60);
let seconds = questionTimeRemain % 60;
//초의 단위가 한자리 수가 되면 앞에 0을 붙여주기
if(seconds <= 9){
seconds = "0"+seconds
}
return minutes + "분 " + seconds + "초";
}
}
- 첫 번째 함수인 reduceTime은 시험 시간을 1초씩 감소시키는 역할을 합니다. 시험 시간이 0이 되면 endQuiz() 함수를 호출하여 시험을 종료합니다. cbtTime 요소에는 현재 시간을 표시합니다.
- 두 번째 함수인 displayTime은 시험 시간을 분:초 형식으로 표시하기 위한 함수입니다. 현재 시간이 0 이하인 경우 "0분 00초"를 반환하여 시험이 종료되었음을 표시합니다. 그 외의 경우에는 분과 초를 계산하여 "분 초" 형식으로 반환합니다. 초의 값이 한자리 수인 경우 "0초" 형식으로 반환될 수 있도록 조건문이 포함되어 있습니다.
이렇게 초의 값이 한 자릿수가 될 때 09초···01초처럼 두 자릿수가 되게 만들어주었습니다.