퀴즈 이펙트 ( 7 ) cbt
퀴즈 이펙트 ( 7-2 ) cbt형식으로 만들었습니다.
[ 처음 화면에 시작하기, 타이머, 문제수 추가 ]
추가 VSCode
<div class="cbt__start">
<div class="cbt__modal1">
<h2>기능사 시험</h2>
<div class="cbt__choice">
<select name="cbtTime" id="cbtTime">
<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_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">
<option value="gineungsaWD2009_05">웹디자인기능사 2009년 5회</option>
<option value="gineungsaWD2010_02">웹디자인기능사 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_04">웹디자인기능사 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>
<button class="minimal">시작하기</button>
</div>
</div>
여러 문제를 선택 할 수 있도록 셀렉트태그를 넣었습니다.
아직 기능을 추가하지 않았지만 여러 문제를 풀어 기능사 시험에 도움이 될 수 있을거 같습니다!
<select>는 HTML에서 드롭다운 리스트를 만들 때 사용하는 태그입니다.
이 태그 안에 <option> 태그를 넣어 선택할 수 있는 목록을 만듭니다.
<option> 태그는 드롭다운 리스트에서 선택 가능한 항목을 정의합니다.
이 태그는 <select> 태그 내부에만 사용할 수 있으며, value 속성을 사용하여 각 항목의 값을 지정할 수 있습니다.
또한, selected 속성을 사용하여 기본 선택 항목을 설정할 수 있습니다.
추가 script
const cbtBtn = document.querySelector(".minimal");
const cbtStart = document.querySelector(".cbt__start");
//시작하기 누르면 모달창 닫기
cbtBtn.addEventListener("click", () => {
cbtStart.style.display = "none";
});
처음 사이트를 열면 나오는 모달창을 시작하면 닫히도록 addEventListener 메서드를 이용했습니다.
//남은 시간
let minutes = 60;
let seconds = 0;
function countdown() {
const timerElement = document.querySelector(".cbt__time");
timerElement.innerHTML = `남은 시간 : ${minutes}분 ${seconds.toString().padStart(2, '0')}초`;
if(seconds === 0){
seconds = 59;
minutes--;
} else {
seconds--;
}
if(minutes < 0){
clearInterval(timer);
alert("시험시간이 끝났습니다. 답안을 제출해주세요.");
}
}
const timer = setInterval(countdown, 1000);
innerHTML 속성을 사용하여 timerElement 요소의 텍스트 내용을 설정합니다. 이 텍스트는 현재 minutes와 seconds 변수에 따라 "남은 시간 : xx분 xx초"로 표시됩니다.
toString() 메서드와 padStart() 메서드를 사용하여 초가 10 미만인 경우 "0x" 형식으로 표시됩니다.
그 다음, if문을 사용하여 seconds 변수가 0이면, minutes 변수를 1분 줄이고 seconds 변수를 59로 재설정합니다. 그렇지 않으면, seconds 변수를 1초 줄입니다.
마지막으로, minutes 변수가 0보다 작아지면, clearInterval() 함수를 사용하여 타이머를 중지하고 alert() 함수를 사용하여 시험 시간이 끝났음을 알리는 메시지를 표시합니다.
setInterval() 함수를 사용하여 countdown() 함수를 1초마다 자동으로 호출하는 타이머를 만듭니다.
setInterval() 함수는 두 개의 인수를 취합니다. 첫 번째 인수는 실행할 함수 또는 코드 블록이며, 두 번째 인수는 함수를 호출하는 간격(밀리초 단위)입니다. 이 함수는 timer 변수에 할당됩니다.
따라서, const timer = setInterval(countdown, 1000); 코드는 1초마다 countdown() 함수가 자동으로 호출되도록 하며, 이것은 타이머를 만드는 데 사용됩니다. 이를 통해 1초마다 시간이 업데이트되어 남은 시간을 계속해서 표시할 수 있습니다.
//문제설명 숨기기
const questionDesc = document.querySelectorAll(".cbt__question__desc");
questionDesc.forEach(el => {
if(el.innerHTML == "undefined"){
el.style.display = "none";
}
});
//이미지 숨기기
const questionImg = document.querySelectorAll(".cbt__question__img");
questionImg.forEach(el => {
if(el.innerHTML == "undefined"){
el.style.display = "none";
}
});
문제중 문제 설명이나 이미지가 없는 경우가 많습니다.
forEach() 메서드를 사용하여 각 요소에 대해 조건을 검사합니다. if 문을 사용하여 요소의 내용이 "undefined"인 경우, style.display 속성을 "none"으로 설정하여 해당 요소를 숨깁니다.
즉, 문제 설명이나 이미지가 없는 경우 해당 요소를 숨기는 것입니다.
따라서, 이 코드를 사용하면 문제에 대한 설명이나 이미지가 없는 경우 "undefined" 가 차지하지 않도록 HTML을 깔끔하게 유지할 수 있습니다.
//보기 체크
const answerSelect2 = (elem) => {
const answer = elem.value;
const answerNum = answer.split("_"); //보기 눌렀을시 [문제번호_보기번호] 를 _기준으로 나눔
const select = document.querySelectorAll(".cbt__omr .omr"); //전체 문항 수 100개
const label = select[answerNum[0]].querySelectorAll("input"); //보기 4개, input아래엔 .cbt__omr, .cbt__quiz 클래스가 다 있음.
label[answerNum[1]-1].checked = true;
const answerInputs = document.querySelectorAll(".cbt__selects input:checked"); //보기를 체크했을 시
cbtRest.innerHTML = questionLength - answerInputs.length; //총 문제수 - 보기 체크 수 = 남은 문제 수
}
//보기 체크2
const answerSelect = (elem) => {
const answer = elem.value;
const answerNum = answer.split("_"); //보기 눌렀을시 [문제번호_보기번호] 를 _기준으로 나눔
const select = document.querySelectorAll(".cbt__quiz .cbt"); //전체 문항 수 100개
const label = select[answerNum[0]].querySelectorAll("input"); //보기 4개
label[answerNum[1]-1].checked = true;
const answerInputs = document.querySelectorAll(".cbt__selects input:checked"); //보기를 체크했을 시
cbtRest.innerHTML = questionLength - answerInputs.length; //총 문제수 - 보기 체크 수 = 남은 문제 수
}
문제에 보기를 체크했을 시 왼쪽문제와 오른쪽 omr카드 쪽을 체크박스를 동기화 시키는 코드입니다.
각 함수에서는 선택한 보기의 값을 가져와서 해당 보기의 input 요소를 체크합니다.
이때, 선택한 보기의 값은 "[문제번호_보기번호]" 형태로 되어 있으며, _를 구분자로 사용하여 split() 메서드를 사용하여 배열로 분할합니다.
그리고 querySelectorAll() 메서드를 사용하여 문제와 보기의 input 요소를 가져와서, 보기 번호를 참조하여 해당 보기의 input 요소를 체크합니다.
마지막으로, querySelectorAll() 메서드를 사용하여 현재 체크된 모든 보기를 가져온 다음, cbtRest 요소의 내용을 업데이트하여 남은 문제 수를 표시합니다.