<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>슬라이드</title>
<link rel="stylesheet" href="css/quiz_exam_slide.css">
<script type="text/javascript" src="js/quiz_exam_slide.js"></script>
</head>
<body>
<div id="start">
<div>상식 테스트</div>
<button id="start">시작하기</button>
</div>
<div id="container">
<div id="header">
<h2>상식 테스트</h2>
<div id="timer"></div>
</div>
<div style="display: flex;">
<!-- 버튼이 가운데 오게 하기 / 그 중 이미지와 가깝게 하기 위해 margin-right:1% 주기 -->
<div style="margin: auto 1% auto auto;">
<button id="previous">◀</button>
</div>
<!-- div를 두개로 감싼이유는 img들을 좌우배치하고 배치된 사진중 한장만 보이게 하기 위함이다.-->
<div id="slide"> <!-- 배치된 img들을 한개의 img만 보이게 가리기 위한 용도로 사용되는 태그임-->
<div id="quiz_display"> <!-- img들을 좌우배치할 태그로서 display 는 flex 로 함 -->
</div>
</div>
<div style="margin: auto auto auto 1%;">
<button id="next">▶</button>
</div>
</div>
<button id=submit type="button" id="btnSubmit">제출하기</button>
<span id="warning">[주의] "제출하기" 버튼을 클릭하는 순간 취소가 불가능하므로 신중히 클릭하십시오!!</span>
<div id="score" style="margin: 10px 0 20px 0;"></div>
<h2 id="msg" style="text-align: center; color: red;"></h2>
</div>
</body>
</html>
window.onload = function(){
let start = false;
document.querySelector("button#start").addEventListener("click",()=>{
document.querySelector("div#start").style.display = "none";
document.querySelector("div#container").style.display = "block";
start = true;
});
const arr_quizData = [
{
question : "문제1. 우리나라의 '초대대통령'은 누구일까요?",
answers : {
1 : "박정희", // 1을 a 로 변경해도 동일하게 출력
2 : "전두환",
3 : "이승만",
4 : "김대중"
},
correct : 3
},
{
question : "문제2. 5천원권 지폐에 있는 과일은?",
answers : {
1 : "복숭아",
2 : "배",
3 : "포도",
4 : "수박"
},
correct : 4
},
{
question : "문제3. 신조어 'TMI'에서 'I'가 의미하는 것은?",
answers : {
1 : "정보",
2 : "인터넷",
3 : "호기심",
4 : "면접",
5 : "이야기"
},
correct : 1
},
{
question : "문제4. 사진속의 인물의 이름은?",
answers : {
1 : "제프 베이조스",
2 : "스티브 잡스",
3 : "마크 저커버그",
4 : "래리 페이지"
},
correct : 2
}
];
const quizDiv = document.querySelector("div#quiz_display"); // 퀴즈문항을 보여줄 장소
// ==== 퀴즈문항을 html 로 만들기 시작 ==== //
let html = ``;
// ◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆
arr_quizData.forEach((item,index) => {
html += `<div id="image" height = "300px"><p id="q${index}">${item.question}</p>`; // 여기서 q 는 새로 만든 id
if(index < 3){
html += `<ol class = 'ol'>`
}
else{
html += `<div id='q4'><img src='images/steven_jobs.png'/>
<ol id = 'ol'>`;
}
// <li> 의 개수가 모두 다르므로 for 문 사용하기
// 어떤 객체의 속성(키)들을 모두 불러올때는 for문에서 of 가 아니라 in 을 사용한다.
for(let property_name in item.answers){
if(index < 3){
html += `<li> <label class = "li_list" for ="${index}${property_name}">${item.answers[property_name]} </label>
<input id = "${index}${property_name}" type="radio" name ="question${index}"
value="${property_name}" /></li>`;
// 객체명.속성명 은 속성명에는 변수가 사용될 수 없다.
// 객체명[속성명] 은 속성명에 변수가 사용될 수 있다.
// ${item.answers[property_name]} 는 "부산" 과 같은 것을 말하는 것이다.
// 라디오는 반드시 name 값이 동일해야 한다.
// value 값은 item.answers 의 속성명인 1 2 3 4 로 되어진다.
}
else{
html += `<li> <label class = "li_list_q4" for ="${index}${property_name}">${item.answers[property_name]} </label>
<input id = "${index}${property_name}" type="radio" name ="question${index}"
value="${property_name}" /></li>`;
}
} // end of for--------------
if(index < 3){
html += `</ol>`;
}
else{
html += `</ol></div>`
}
html += `<div class='ox' id='ox${index}''></div></div>`; // 퀴즈 문항에 대해 정답인지 틀린것인지 보여줄 장소
}); // end of arr_quizData.forEach((item,index)------------
// ◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆
quizDiv.innerHTML = html;
// ==== 퀴즈문항을 html 로 만들기 끝 ==== //
///////////////////////////////////////////////////////////////////////////////////
const btnSubmit = document.querySelector("button#submit");
// === "제출하기" 버튼 클릭시 이벤트 처리하기 시작 === //
// 제출하기 버튼 클릭시 이벤트함수 만들기
const handleSubmit = function(){
alert("제출이 완료되었습니다.")
// 타이머 삭제하기
clearInterval(interval_timer); // interval_timer 는 중단해야할 setInterval 함수를 가리키는 것이다.
timerDiv.innerHTML = `00:00`; // 제출 후 시간 00:00 으로 지정
// 제출 후 "제출하기" 버튼 비활성화 하기
btnSubmit.disabled = true; // "제출하기" 버튼 비활성화
check(); // 채점하는 함수 호출
}
btnSubmit.addEventListener('click',handleSubmit);
// === "제출하기" 버튼 클릭시 이벤트 처리하기 끝 === //
//////////////////////////////////////////////////////////////////////////////////
const timerDiv = document.querySelector("div#timer"); // 타이머를 보여줄 장소
let time = 600; // 타이머 시간을 10분으로 지정함.
// ==== 타이머 함수 만들기 시작 ==== //
const timer = function(){
if(time < 0){ // 시간이 다 된 경우
alert("시험시간 종료!!\n자동으로제출됩니다.");
// 타이머 삭제하기
clearInterval(interval_timer); // interval_timer 는 중단해야할 setInterval 함수를 가리키는 것이다.
// 제출 후 "제출하기" 버튼 삭제하기
btnSubmit.disabled = true; // "제출하기" 버튼 비활성화
check(); // 채점하는 함수 호출
}
else{
if(start){
let minute = "";
let second = "";
minute = parseInt(time/60); // 소수부는 없애 버리고 정수부만 가져오는 것이다.
if(minute < 10){
minute = "0" + minute;
}
second = time%60; // time 을 60으로 나누었을때의 나머지
if(second < 10){
second = "0" + second;
}
timerDiv.innerHTML = `시간 ${minute}:${second}`;
time--;
}
} // end of if~else-------------------------------
}
// ==== 타이머 함수 만들기 끝 ==== //
timer(); // 타이머 함수 호출하기 => 존재할 경우 로딩하자 나온다. 없을 경우 1초 있다가 나온다.
// 1초 마다 주기적으로 타이머 함수가 호출되도록 지정한다.
// const interval_timer = setInterval(function(){timer();},1000);
// 또는
const interval_timer = setInterval(timer,1000);
///////////////////////////////////////////////////////////////////////////////////
// === 채점하는 함수 만들기 시작 === //
const check = function(){
let answer_cnt = 0; // 정답개수 누적용
// 문항 수 만큼 채점하기
arr_quizData.forEach((item,index) => {
// console.log(`${index+1}번 문제 정답은 ${item.correct}`);
/*
1번 문제 정답은 3
2번 문제 정답은 2
3번 문제 정답은 4
4번 문제 정답은 2
*/
// === 퀴즈 문항 뒤에 정답번호 공개하기 === //
// 정답을 보여주기전 문제를 읽어와서 확인해본다.
const question = document.querySelector(`p#q${index}`).innerHTML;
// console.log(question);
/*
문제1. 대한민국의 수도는?
문제2. 1+1은?
문제3. 미국의 수도는?
문제4. 사진속의 인물의 이름은?
*/
// 원래 있던 문제 장소에 새롭게 덮어쓰기(정답표출 추가) => 문제에다가 뒤에 정답을 붙여서 보여준다.
document.querySelector(`p#q${index}`).innerHTML = question + ` <span style='color:red; font-weight:bold;'>${item.correct}</span>`;
// === 해당 문제의 라디오 개수가 몇개인지 알아보기 === //
let radio_length = document.querySelectorAll(`input[name ="question${index}"]`).length;
// console.log(`${index+1}번 문제의 라디오 개수는 ${radio_length} 개 입니다.`);
/*
1번 문제의 라디오 개수는 4 개 입니다.
2번 문제의 라디오 개수는 4 개 입니다.
3번 문제의 라디오 개수는 5 개 입니다.
4번 문제의 라디오 개수는 4 개 입니다.
*/
let isCheckAnswer = false; // 라디오의 선택유무 검사용
// 해당 문항마다 선택을 했는지 안했는지 알아보기
for(let i=0; i<radio_length; i++){
if(document.querySelectorAll(`input[name ="question${index}"]`)[i].checked){
isCheckAnswer = true;
break;
}
} // end of for-----------------------------
// console.log(`${index+1}번 문제 답을 선택하셨나요? ${isCheckAnswer}`);
/*
1번 문제 답을 선택하셨나요? false
2번 문제 답을 선택하셨나요? false
3번 문제 답을 선택하셨나요? true
4번 문제 답을 선택하셨나요? true
*/
let user_answer;
if(isCheckAnswer){ // 사용자가 답을 선택한 경우
// :checked 은 라디오 중 에 선택되어진 라디오를 말한다.
user_answer = document.querySelector(`input[name ="question${index}"]:checked`).value
}
else{ // 사용자가 답을 선택하지 않은 경우
user_answer = "선택안함";
}
// console.log("사용자가 선택한 답번호 => ", user_answer);
if(user_answer == item.correct){
answer_cnt++;
document.querySelector(`div#ox${index}`).innerHTML = `결과 : <span style='color:blue;'>정답</span>`;
}
else{
document.querySelector(`div#ox${index}`).innerHTML = `결과 : <span style='color:red;'>오답</span>`;
}
}); // end of arr_quizData.forEach((item,index) => {})------------
document.querySelector("div#score").innerHTML = `<span style='font-weight:bold;'>정답개수 : ${answer_cnt}</span>`;
}
// === 채점하는 함수 만들기 끝 === //
//////////////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////////////////
let current_index = 0; // 현재 인덱스 번호
let positionValue = 0; // images 위치값
const image_width = 800; // 한번 이동 시 image_width 만큼 이동한다.
const btn_previous = document.querySelector("button#previous");
const btn_next = document.querySelector("button#next");
const images = document.querySelector("div#quiz_display");
/////////////////////////////////////////////////////////////////////////
// === 이전으로 이동하는 함수 === //
const func_previous = function(){
if(current_index > 0){ // 현재 인덱스번호가 처음이 아닌 두번째 이상인 경우
// btn_next.setAttribute('disabled', false);
// 또한
btn_next.removeAttribute('disabled'); // 다음 버튼을 활성화 상태로 만든다.
// images 의 위치를 오른쪽으로 이동시키도록 IMAGE_WIDTH 만큼 증가시켜 positionValue에 저장한다.
positionValue += image_width; // 이미지 이동
// x축 방향(가로방향)으로 positionValue 만큼 이동하도록 변형시킨다.
images.style.transform = `translateX(${positionValue}px)`;
// 현재 인덱스번호를 1 감소 시킨다.
current_index--;
// 메시지가 안나오게 하기
document.querySelector("h2#msg").innerHTML = "";
}
else{ // 현재 인덱스번호가 처음인 경우
// 처음 사진일 때 다음버튼을 disabled 로 만든다.
btn_previous.setAttribute('disabled',true);
document.querySelector("h2#msg").innerHTML = "처음 문제 입니다.";
}
}
// === 다음으로 이동하는 함수 === //
const func_next = function(){
if(current_index < 3){ // 현재 인덱스번호가 마지막(지금은 4)이 아닌 경우
// btn_previous.setAttribute('disabled', false);
// 또한
btn_previous.removeAttribute('disabled'); // 이전 버튼을 활성화 상태로 만든다.
// images 의 위치를 왼쪽으로 이동시키도록 IMAGE_WIDTH 만큼 감소시켜 positionValue에 저장한다.
positionValue -= image_width; // 이미지 이동
// x축 방향(가로방향)으로 positionValue 만큼 이동하도록 변형시킨다.
images.style.transform = `translateX(${positionValue}px)`;
// 현재 인덱스번호를 1 증가 시킨다.
current_index++;
// 메시지가 안나오게 하기
document.querySelector("h2#msg").innerHTML = "";
}
else{ // 현재 인덱스번호가 마지막(지금은 3)인 경우
// 마지막 사진일 때 다음버튼을 disabled 로 만든다.
btn_next.setAttribute('disabled',true);
document.querySelector("h2#msg").innerHTML = "마지막 문제 입니다.";
}
}
////////////////////////////////////////////////////////////////////////////////////////////////////
// 이전 버튼은 초기화로 사용하지 못하도록 disabled 로 만든다.
btn_previous.setAttribute('disabled', true);
// btn_next.addEventListener('click',function(){}); 이 방법도 있지만 함수를 밖으로 꺼낼 수 있다.
// 이전버튼 클릭시 이전으로 이동하는 함수를 호출한다.
btn_previous.addEventListener('click',func_previous);
// 다음버튼 클릭시 다음으로 이동하는 함수를 호출한다.
btn_next.addEventListener('click',func_next);
} // end of window.onload = function()--------------------
@charset "UTF-8";
div#start{
border: solid 0px red;
width: 40%;
margin: auto;
margin-top: 200px;
min-width: 500px;
}
div#start > div {
border: solid 0px red;
text-align: center;
font-size: 50pt;
font-weight: bold;
}
div#start > button#start{
border: solid 0px blue;
border-radius: 0%;
width: 200px;
margin-left : 150px;
}
/* ======================================= */
div#container {
border: solid 5px #000033;
width: 70%;
margin: 0 auto; /**중앙 정렬한다.**/
min-width: 1000px;
display: none;
}
/* ======================================== */
div#header{
border-bottom: solid 3px navy;
display: flex;
padding: auto;
}
div#header > h2{
margin-left: 40%;
text-align: center;
font-size: 30pt;
vertical-align: middle;
}
/* 타이머 디자인 */
div#timer {
border: solid 0px gray;
width: 30%;
height: 50px;
color: blue;
font-size: 30pt;
text-align: right;
margin-top: 5%;
}
/* ======================================== */
/* ======================================== */
div#slide {
border: solid 3px #000099;
width: 800px;
height: 300px;
overflow: hidden;
padding: 0; /* 기본값이 0이아니다. */
margin-top: 5%;
border-radius: 30px;
}
div#slide > div#quiz_display {
border: solid 0px red;
display: flex;
width: 3600px ; /* 900px 의 4가지 문제이니 4배를 해주어야 한다 */
height: 300px;
transition: transform 1s;
padding: 0; /* 기본값이 0이아니다. */
}
div#slide >div#quiz_display > div#image{
border: solid 0px green;
margin: 0;
width: 800px;
}
div#quiz_display > div#image > p{
border: solid 0px blue;
font-size: 20pt;
text-align: center;
font-weight: bold;
}
div#quiz_display > div#image > div#q4{
border: solid 0px red;
display: flex;
}
div#q4> img, ol#ol{
border: solid 0px red;
width: 20%;
margin: auto;
}
ol.ol{
padding-left: 350px;
}
div#quiz_display > div#image > div.ox{
font-weight: bold;
padding-left: 500px;
}
/* ============================================== */
/* 버튼디자인 */
button {
width: 50px;
height: 50px;
background-color: #646464;
color: white;
font-size: 20pt;
border-radius: 50%;
}
button:active { /* 버튼을 클릭하는 동안 색을 바꾼다. */
background-color:#3e3e3e;
}
button:disabled { /* 버튼 속성이 disabled되면 색을 바꾼다. */
background-color: white; /* 있는데 없는척 */
border: none;
}
button:disabled~span#warning{ /* ~ 자식들을 나타날때도 사용하지만 만약(if)라는 뜻도 가지고 있다 */
display: none;
}
span#warning {
border: solid 0px red;
margin-left: 10px;
padding: 5px 10px;
font-size: 10pt;
font-weight: bold;
}
button#submit{
width: 15%;
height: 35px;
font-size: 15pt;
border-radius: 0%;
border: solid 0px red;
margin: 2% 45% ;
}
/* ===================================================== */
div#image label.li_list{
border : solid 0px red;
display: inline-block;
width: 70px;
}
div#image label.li_list_q4{
border : solid 0px red;
display: inline-block;
width: 120px;
}
div#score > span {
margin-left: 10%;
}