728x90
퀴즈 사이트 만들기 ! ( 객관식유형 * 60문제 한번에 만들기+json형식 ) ver.3
어제 만든것에서 오늘은 좀더 소스를 다듬을거에요
사용자 이름 입력 받는것 & timer 스크립트를 변경했어요
전체 소스는 요기
주요 소스를 볼게요 !
<div class="cbt__conts">
<div class="cbt__quiz">
<div class="cbt good">
<div class="cbt__question"><span>1</span>. 객체지향 프로그램에서 데이터를 추상화하는 단위는?</div>
<div class="cbt__question__img"><img src="img/gineungsaWD2023_01_01.jpg" alt="기능사"></div>
<div class="cbt__selects">
<input type="radio" id="select1">
...
</div>
<div class="cbt__desc">객체지향언어는 이다. 객체지향언어는 이다. 객체지향언어는 이다. 객체지향언어는 이다. 객체지향언어는 이다. 객체지향언어는 이다.</div>
<div class="cbt__keyword">객체지향언어</div>
</div>
</div>
</div>
<div class="cbt__aside">
<div class="cbt__info">
<div>
<button class="cbt__submit">제출하기</button>
<span class="cbt__time"></span>
</div>
<div>
<div class="cbt__title">수험자 : <em class="cbt__name"></em></div>
<div class="cbt__exam">
<span>전체 문제수 : <em class="cbt__length">0</em>문항</span>
<span>남은 문제수 : <em class="cbt__rest">0</em></span>
</div>
<div class="cbt__score hide">
<span>점수 : <em >0</em></span>
</div>
</div>
</div>
<div class="cbt__omr">
<div class="omr">
<strong>1</strong>
</label>
</div>
</div>
</div>
<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="gineungsaJC2011_05">정보처리기능사 2011년 5회</option>
</select>
<select name="cbtTime" id="cbtTime" onchange="changeSelect(this)">
<option value="gineungsaWD2009_05">웹디자인기능사 2009년 5회</option>
<option value="gineungsaWD2016_04">웹디자인기능사 2016년 4회</option>
</select>
</div>
<div class="cbt__view">
<input type="text" id='cbtUserName' autofocus placeholder="이름적어주세요"/>
<span class="subject">과목을 선택하세요.</span>
</div>
<button class="cbt__start__btn">시작하기</button>
</div>
</div>
위처럼 body영역엔 소스가 없고
스크립트에서 소스를 cbt_quiz, cbt_omr에 소스를 뿌려 주는건 ver1과 동일해요
모달창을 시작할때 실행되게끔 해놨어요
오늘의 과제
- 이름 입력
- 시간->0 일때 처리
- 점수결과
이름을 넣어주는 부분 깔끔하게 !
이름을 넣어주는 text박스의 값이 공백이면 ''이기 때문에 입력을 하지않을경우 바보라고 설정하고
입력받을경우 값을 넣어주도록했어요
//이름가져오기 입력받은값을 가져오기 or 없으면 바보라고 출력되요
let inputString = document.querySelector("#cbtUserName").value;
(inputString == '')?document.querySelector(".cbt__name").innerHTML = "바보" : document.querySelector(".cbt__name").innerHTML = inputString ;
남은시간이 0 일때 처리 & 타이머 종료시 처리
// 1초마다 실행되게 setInterval함수를 썻어요 !
questionTime = setInterval(reduceTime,1000);
// 시간 설정
const reduceTime = () => {
questionTimeRemain--;
if(questionTimeRemain ==0)endQuiz();
cbtCountTime.innerHTML=displayTime();
}
//시간표시
const displayTime = () =>{
if(questionTimeRemain <=0){
return "0분 00초";
}else{
let minutes = Math.floor(questionTimeRemain/60);
let seconds = (Math.floor(questionTimeRemain%60)<=10)?"0"+Math.floor(questionTimeRemain%60):Math.floor(questionTimeRemain%60);
return `${minutes}분 ${seconds}초 `;
//초의 단위가 한자리일경우 앞에 0을 붙여주기
}
}
// 시험 끝
const endQuiz =()=>{
answerQuiz();
alert("시험끝");
}
//setInterval함수 종료 시키기 !
//clearInterval(questionTime);
// 요기는 저가 짠 소스에용 변수값을 --하는는 위 소스가 좀더 가독성이 좋네용
// 시험시간20분계산 분 * 초 * 1000 1분의1초
const countTime = 20 * 60 * 1000+1500;
// 끝나는 기준 시간(현재 시간 + 20분+2000)을 계산 updateTimer 불러올때 +1.5초추가 해서계산
// 끝나는 기준시간이에용 고정값인 시간입니다.
let endTime = Date.now() + countTime;
function updateTimer() {
// 남은 시간을 계산합니다.
const leftTime = endTime - Date.now();
// 시, 분, 초를 계산합니다. 시간은 쓰지않아서 주석처리 시험시간은 20분으로 설정!
// const hours = Math.floor(leftTime / countTime);
const minutes = Math.floor((leftTime % countTime) / (60 * 1000));
const seconds = Math.floor((leftTime % (60 * 1000)) / 1000);
// 타이머를 화면에 출력합니다.
cbtCountTime.innerText=`${minutes}분 ${seconds}초`;
// 남은 시간이 없으면 타이머를 멈춥니다.
if (leftTime <= 0){
//setInterval을 종료할땐 clearInterval(timer) 이런형식으로해요
//timer함수선언해서 요값이 들거가 있는거에요
clearInterval(timer);
//시간종료 제출하기 & 시간대신 시간초과ㅜ표시
answerQuiz();
cbtCountTime.innerText=`시간초과ㅜ`;
}
}
// setInterval을 이용하면 1초마다 타이머가 실행되게할수있어요
alert("시험끝") 으로 처리를 하고
answerQuiz()을 실행하여 채점을 하도록했습니다.
또한
setInterval() 메서드를 종료시켜야 해서
clearInterval(questionTime) 요부분을 채점할경우 실행되게 했어요 !
정답 확인하기 & 점수 확인
const answerQuiz = () =>{
//모든 체크 답안 가져오기
const cbtSelects = document.querySelectorAll(".cbt__selects");
//모든 정보를 가져와서 forEach로 값을 비교할거에요
questionAll.forEach((question, number) =>{
const quizSelectsWrap = cbtSelects[number];
const userSelector = `input[name=select${number}]:checked`;
//객관식 보기 문제에 체크유무 상관없이 값을 가져오기
const userAnswer = (quizSelectsWrap.querySelector(userSelector)||{}).value;
//userAnswer의 값유무에 따라 slice하여 값을 가져와요 없으면 undefined
const numberAnswer = userAnswer ? userAnswer.slice(-1) : undefined;
//정답을 가져와서 비교해요 그리고 정답일경우 cbtQuizScore를 증가시켜요!
if(Number(numberAnswer)+1 == question.Answer){
cbtSelects[number].parentElement.classList.add("good");
cbtQuizScore++;
}else{
cbtSelects[number].parentElement.classList.add("bad");
//오답일경우 정답표시
const label = cbtSelects[number].querySelectorAll("label");
label[question.Answer-1].classList.add("correct");
}
//해설이 없다면 출력하지 않고 있을 경우에만 출력하게만들었어요
const quizDesc = document.querySelectorAll(".cbt__desc");
if(quizDesc[number].innerText == "undefined"){
quizDesc[number].classList.add("hide");
} else {
quizDesc[number].classList.remove("hide");
}
});
// 점수 입력
cbtScore.querySelector("em").innerHTML =Math.floor(cbtQuizScore/questionAll.length*100)+" 점";
// 남은문항 & 전체문항 삭제 & 점수 보이기
cbtExam.classList.add("hide");
cbtScore.classList.remove("hide");
//타이머종료 & 타이머 문구 시험종료로 변경
cbtCountTime.innerHTML=" 시험종료 !";
clearInterval(questionTime);
}
cbtQuizScore를 증가시켜 점수를 구하는 로직을 마지막에 추가시켜줬어요
오늘두 고생하셨습니다.