728x90
반응형
퀴즈 이펙트 : 객관식 확인하기 : CBT 유형(json) 보충
https://dongjin6539.tistory.com/64 블로그 보충
코드 보기(HTML, JAVASCRIPT / CSS1 / CSS2 / JSON) / 완성화면
코드 블럭 추가
<div class="cbt__start">
<div class="cbt__modal1">
<h2>기능사 시험</h2>
<div class="cbt__choice">
<select name="cbtTime" id="cbtTime">
<option value="gineungsaJC2010_02">정보처리기능사 2010년 2회</option>
</select>
<select name="cbtTime" id="cbtTime">
<option value="gineungsaWD2011_02">웹디자인기능사 2011년 2회</option>
</select>
</div>
<button class="minimal">시작하기</button>
</div>
</div>
구성
- 모달 창을 만들어줍니다.
- 모달 창에 문제 유형을 선택하는 것을 만들어줍니다.
- 시험을 시작하는 버튼을 만들어줍니다.
CSS 추가
.cbt__start {
position: fixed;
left: 0;
top: 0;
width: 100%;
height: 100vh;
background-color: rgba(255, 255, 255, 0.4);
z-index: 10000;
backdrop-filter: blur(10px);
display: flex;
align-items: center;
justify-content: center;
}
.cbt__start > div {
width: 50%;
height: 50vh;
background-color: #fff;
border: 8px ridge #cacaca;
text-align: center;
}
.cbt__modal1 h2 {
font-size: 30px;
margin: 30px;
}
.cbt__modal1 select {
border: 1px solid #cacaca;
padding: 10px 30px;
margin-bottom: 40px;
font-family: 'PyeongChang';
}
.minimal {
box-shadow: 2px 2px 5px rgba(0,0,0,0.15);
background: #cacaca;
display: grid;
align-content: center;
justify-content: center;
border-radius: 5px;
width: 300px;
height: 80px;
margin: 0 auto;
font-family: 'PyeongChang';
border: 1px solid #cacaca;
}
- 각 태그에 맞게 적절한 스타일을 입력해줍니다.
JAVASCRIPT
<script>
const cbtRest = document.querySelector(".cbt__rest");
const cbtLength = document.querySelector(".cbt__length");
let questionLength = 0; // 전체 문제 수
let questionRest = questionLength; // 남은 문제 수
// 모달 창 없애기
const cbtBtn = document.querySelector(".minimal");
const cbtStart = document.querySelector(".cbt__start");
cbtBtn.addEventListener("click", () => {
cbtStart.style.display = "none";
});
// 타이머 만들기
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);
// 문제 만들기
const newQuestion = () => {
const questionDesc = document.querySelectorAll(".cbt__question__desc");
questionDesc.forEach(el => {
if(el.innerHTML == "undefined"){
el.style.display = "none";
}
});
};
// 보기 체크
const answerSelect2 = (elem) => {
const answer = elem.value; // 문제 보기의 값
const answerNum = answer.split("_");
const select = document.querySelectorAll(".cbt__omr .omr"); // 전체 문제 갯수(omr)
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;
};
// 보기 체크2
const answerSelect = (elem) => {
const answer = elem.value;
const answerNum = answer.split("_");
const select = document.querySelectorAll(".cbt__quiz .cbt"); // 전체 문제 갯수(문제)
const label = select[answerNum[0]].querySelectorAll("input"); // 보기 4개
label[answerNum[1]-1].checked = true;
const answerInput = document.querySelectorAll(".cbt__selects input:checked");
cbtRest.innerHTML = questionLength - answerInput.length;
};
</script>
자바스크립트 구성
모달 창 없애기
- 모달 창의 시작하기 버튼과 전체 구역을 선택자로 변수를 저장해줍니다.
- 버튼을 클릭했을 때 전체 구역이 사라지도록 style.display="none";을 입력해줍니다.
타이머 만들기
- 분과 초를 변수로 숫자 데이터를 저장해줍니다.
- 함수를 이용해서 실행해주고 안에 시간이 있는 부분을 선택자로 만들어주고 선택자에 데이터를 입력하기 위해 .innerHTML을 써서 입력해줍니다.
- if문을 사용해서 초가 0이 되면 초가 59로 바뀌게 하고 분이 --연산자를 이용해 감소하게 해줍니다. 초가 0이 아니면 초가 --연산자를 이용해 감소하게 해줍니다.
- 또 if문을 사용해서 분이 0보다 작으면 타이머를 멈추게 해줍니다.
- 타이머 변수를 만들어 실행해줍니다. 1000을 쓴 이유는 스크립트에서 밀리초로 설정되어있어서 1000밀리초가 1초를 나타냅니다.
문제의 보기 설명 없애기
- 각 문제별로 문제의 보기 설명이 없을 수가 있습니다.
- 문제를 만들 때 보기가 나오거나 안나와야 하기 때문에 문제 만들기 함수에 입력을 해줍니다.
- 문제의 보기 설명이 위치해 있는 곳을 선택자로 변수를 저장해줍니다.
- 그 위치의 값이 undefined이면 사라지게 하기 위해 style.display="none";를 입력해서 없애줍니다.
보기 연동하기(문제의 보기, OMR 보기)
- 전에 스크립트 코드에 문제의 보기 부분과 OMR 보기 부분에 onclick="answerSelect2(this)", onclick="answerSelect(this)" 각각 입력해줍니다.
- 각각 함수를 만들어줍니다.
- 변수 answer로 onclick의 값을 저장해줍니다.
- 변수 answerNum으로 저장된 anwer의 값을 split("_")로 값을 저장해줍니다.
- answerSelect2 부분에는 문제의 전체 문제 보기를 선택자로 만들고 answerSelect 부분에는 omr의 전체 문제 보기를 선택자로 만들어줍니다.
- 전체 문제의 보기 input을 선택자로 만들어 체크가 된게 true로 만들어주면 서로 연동됩니다.
문제를 풀었을 때 남은 문항 수 줄어들게 하기
- 전체 문제와 남은 문제의 위치를 선택자 변수를 만들어줍니다.
- 전체 문제 수와 남은 문제 수의 데이터를 저장해줍니다.
- 문제를 풀었을 때 남은 문항 수가 줄어들게 하니까 보기 체크 함수 부분에 입력해줍니다. 문제의 보기와 omr 보기를 선택했을 때니까 두 군데 다 입력해줍니다.
- 먼저 보기가 선택 됐을 때를 선택자로 만들어줍니다.
- 선택자 남은 문항에 .innerHTML를 사용해서 데이터를 입력해줍니다.
- 남은 문항 수는 전체 문항 수에 보기가 선택 된 수를 빼주면 됩니다.
참고
- 속성, 메서드
속성, 메서드 | 설명 |
toString( ) | 문자열을 반환합니다. |
padStart( ) | 현재 문자열의 시작을 다른 문자열로 채워, 주어진 길이를 만족하는 새로운 문자열을 반환합니다. 채워넣기는 대상 문자열의 시작(좌측)부터 적용됩니다. |
clearInterval | 호출로 이전에 설정된 시간 제한 반복 작업을 취소합니다. |
setInterval | 호출 사이에 고정된 시간이 지연되면 이를 반복적으로 호출을 실행합니다. |
split( ) | 문자열 객체를 지정한 구분자를 이용하여 여러 개의 문자열로 나눕니다. |
728x90
반응형