<코딩 자격증 없이 퀴즈앱을 만들자 3편>
지난번에는 온라인 퀴즈앱 객관식에 이어 주관식 문제를 완성했었다.
마지막 남은 나의 미션은 녹음 파일을 저장하고 듣기 평가 문제로 바꾸는 것이다.
이를 해결하기 위해 또 다시 유튜브를 검색했다.
Invention Tricks 채널에 가면 오디오 버튼 관련 동영상을 찾을 수 있다.
이걸 참고하며 만들었는데 코드를 쓰면서 어려움이 많았다.
내가 만든 온라인 퀴즈앱은 타이머, 정답 체크, 여러개의 문제 등으로 이루어져 있기에 버튼만 만들어서 되는게 아니었다.
또 머리를 싸매고 의자 앞에 앉았다.
구글과 씨름을 하며 고생한 끝에 완성하기는 했다..

항상 하는 이야기지만 어설픈 코드이기에 양해 부탁드린다..
mp3 파일은 어떤 것이든 상관없다.
media 폴더를 만들고 그 안에 음악을 저장한 다음, 쉬운 이름으로 바꾸면 된다.
자, 이제 드디어 온라인 퀴즈앱 마지막 소스다.
설마 다른 미션은 없겠지..

Quiz App index.html
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewpoint" content="width=device-width, initial-scale=1.0">
<title>타이틀 입력</title>
<!-- FontAwesome CDN Link for Icons -->
<link rel="stylesheet" href="style.css">
<script src="https://kit.fontawesome.com/be98661673.js" crossorigin="anonymous"></script>
<!-- fontawesome 사이트 가입 -->
</head>
<body>
<!-- start quiz button -->
<div class="start_btns">
<div class="start_btn1"><a href="1.html"><button>Beginner</button></a></div>
<div class="start_btn2"><a href="2.html"><button>Intermediate</button></a></div>
</div>
</body>
</html>
1.html
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewpoint" content="width=device-width, initial-scale=1.0">
<title>타이틀 입력</title>
<!-- FontAwesome CDN Link for Icons -->
<link rel="stylesheet" href="style.css">
<script src="https://kit.fontawesome.com/be98661673.js" crossorigin="anonymous"></script>
<!-- fontawesome 사이트 가입 -->
<link rel="shortcut icon" href="data:image/x-icon;," type="image/x-icon" >
</head>
<body>
<!-- start quiz button -->
<div class="start_btns">
<div class="start_btn1"><button>LEVEL 1</button></div>
</div>
<!-- info box -->
<div class="info_box">
<div class="info_title">
<span>Some Rules of this Quiz</span>
</div>
<div class="info_list">
<div class="info">1. Lorem ipsum dolor sit amet <span>consectetur</span> adipisicing elit.</div>
<div class="info">2. Lorem ipsum dolor sit amet consectetur adipisicing elit.</div>
<div class="info">3. Lorem ipsum dolor sit amet consectetur adipisicing elit.</div>
<div class="info">4. Lorem ipsum dolor sit amet consectetur adipisicing elit.</div>
<div class="info">5. Lorem ipsum dolor sit amet consectetur adipisicing elit.</div>
</div>
<div class="buttons">
<button class="quit">Exit Quiz</button>
<button class="restart">Continue</button>
<!-- <button class="restart2">Continue2</button> -->
</div>
</div>
<!-- quiz box -->
<div class="quiz_box">
<header>
<div class="title">Spanish Quiz Application</div>
<div class="timer">
<div class="time_text">Time Left</div>
<div class="timer_sec">15</div>
</div>
<div class="time_line"></div>
</header>
<section>
<div class="que_text">
<!-- <span>What is your name?</span> -->
</div>
<div class="word-input-box">
<input type="text" class="word-input" placeholder="typing here">
<input type="submit" value="Submit" class="word-submit">
</div>
<div class="msg">Your answer is ..</div>
<div class="audio_list">
<audio class="audio">
<source src="media/1.mp3" type="audio/mpeg">
</audio>
<audio class="audio">
<source src="media/2.mp3" type="audio/mpeg">
</audio>
<audio class="audio">
<source src="media/3.mp3" type="audio/mpeg">
</audio>
<audio class="audio">
<source src="media/4.mp3" type="audio/mpeg">
</audio>
<audio class="audio">
<source src="media/5.mp3" type="audio/mpeg">
</audio>
</div>
<div class="audio_buttons">
<button class="audio_btn1">Play
<div class="iconPlay"><i class="fas fa-play"></i></div>
<!-- <div class="iconPause"><i class="fas fa-pause"></i></div> -->
</button>
<button class="audio_btn2">Stop
<div class="iconStop"><i class="fas fa-stop"></i></div>
</button>
</div>
<!--여러줄 쓸때 <textarea class="word-input" name="content" cols="40" rows="5" >
typing here
</textarea>
</div>
<input type="submit" value="Submit"> -->
<div class="option_list">
<!-- <div class="option">
<span>Lorem, ipsum dolor.</span>
<div class="icon tick"><i class="fas fa-check"></i></div>
</div>
<div class="option">
<span>Lorem, ipsum dolor.</span>
<div class="icon cross"><i class="fas fa-times"></i></div>
</div>
<div class="option">
<span>Lorem, ipsum dolor.</span>
</div>
<div class="option">
<span>Lorem, ipsum dolor.</span>
</div> -->
</div>
</section>
<!-- quiz box footer -->
<footer>
<div class="total_que">
<!-- <span><p>2</p>of<p>5</p>Questions</span> -->
</div>
<button class="next_btn"></button>
</footer>
</div>
<!-- result box -->
<div class="result_box">
<div class="icon">
<i class="fas fa-crown"></i>
</div>
<div class="complete_text">Yoe've completed the Quiz!</div>
<div class="score_text">
<!-- <span>and sorry, You got only <p>2</p> out of <p>5</p></span> -->
</div>
<div class="buttons">
<button class="restart">Replay Quiz</button>
<button class="quit">Quit Quiz</button>
</div>
</div>
<script src="js/questions.js"></script>
<script src="js/script.js"></script>
</body>
</html>
2.html
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewpoint" content="width=device-width, initial-scale=1.0">
<title>타이틀 입력</title>
<!-- FontAwesome CDN Link for Icons -->
<link rel="stylesheet" href="style.css">
<script src="https://kit.fontawesome.com/be98661673.js" crossorigin="anonymous"></script>
<!-- fontawesome 사이트 가입 -->
</head>
<body>
<!-- start quiz button -->
<div class="start_btns">
<div class="start_btn1"><button>LEVEL 2</button></div>
</div>
<!-- info box -->
<div class="info_box">
<div class="info_title">
<span>Some Rules of this Quiz</span>
</div>
<div class="info_list">
<div class="info">1. Lorem ipsum dolor sit amet <span>consectetur</span> adipisicing elit.</div>
<div class="info">2. Lorem ipsum dolor sit amet consectetur adipisicing elit.</div>
<div class="info">3. Lorem ipsum dolor sit amet consectetur adipisicing elit.</div>
<div class="info">4. Lorem ipsum dolor sit amet consectetur adipisicing elit.</div>
<div class="info">5. Lorem ipsum dolor sit amet consectetur adipisicing elit.</div>
</div>
<div class="buttons">
<button class="quit">Exit Quiz</button>
<button class="restart">Continue</button>
<!-- <button class="restart2">Continue2</button> -->
</div>
</div>
<!-- quiz box -->
<div class="quiz_box">
<header>
<div class="title">Spanish Quiz Application</div>
<div class="timer">
<div class="time_text">Time Left</div>
<div class="timer_sec">15</div>
</div>
<div class="time_line"></div>
</header>
<section>
<div class="que_text">
<!-- <span>What is your name?</span> -->
</div>
<div class="option_list">
<!-- <div class="option">
<span>Lorem, ipsum dolor.</span>
<div class="icon tick"><i class="fas fa-check"></i></div>
</div>
<div class="option">
<span>Lorem, ipsum dolor.</span>
<div class="icon cross"><i class="fas fa-times"></i></div>
</div>
<div class="option">
<span>Lorem, ipsum dolor.</span>
</div>
<div class="option">
<span>Lorem, ipsum dolor.</span>
</div> -->
</div>
</section>
<!-- quiz box footer -->
<footer>
<div class="total_que">
<!-- <span><p>2</p>of<p>5</p>Questions</span> -->
</div>
<button class="next_btn">Next Que</button>
</footer>
</div>
<!-- result box -->
<div class="result_box">
<div class="icon">
<i class="fas fa-crown"></i>
</div>
<div class="complete_text">Yoe've completed the Quiz!</div>
<div class="score_text">
<!-- <span>and sorry, You got only <p>2</p> out of <p>5</p></span> -->
</div>
<div class="buttons">
<button class="restart">Replay Quiz</button>
<button class="quit">Quit Quiz</button>
</div>
</div>
<script src="js/questions2.js"></script>
<script src="js/script2.js"></script>
</body>
</html>
내가 만든 온라인 퀴즈앱 뮤직 플레이어 버튼은 유튜브 영상과 다르다.
살짝 눌리는 느낌이 나게끔 수정했고, 색상, 테두리, 정답 확인을 아래에 정렬하는 등 이런 저런 실험을 해봤다.
처음에는 두번째 노래로 넘어가지 않아 고생했는데 어떻게든 만들어내긴 했다.
마지막 문제에서는 정답 확인도 없이 result 화면으로 넘어가 버려서 좌절하기도 했었다.

style.css
/* importing google fonts */
@import url('https://fonts.googleapis.com/css2?family=Poppins:wght@200;300;400;500;600;700&display=swap');
*{
margin: 0;
padding: 0;
box-sizing: border-box;
font-family: 'Poppins', sans-serif;
}
body{
background: #0984e3;
}
.info_box,
.quiz_box,
.result_box{
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
box-shadow:0px 4px 8px 0 rgba(0,0,0,0.2),
0px 6px 20px 0 rgba(0,0,0,0.19);
transition:all 0.3s ease;
}
.start_btns{
position:absolute;
/* display:inline-block; */
top:50%;
left:50%;
transform: translate(-50%, -50%);
}
.start_btn1, .start_btn2{
box-shadow:0px 4px 8px 0 rgba(0,0,0,0.2),
0px 6px 20px 0 rgba(0,0,0,0.19);
transition:all 0.3s ease;
margin:30px;
}
.info_box.activeInfo,
.quiz_box.activeQuiz,
.result_box.activeResult{
z-index: 5;
opacity: 1;
pointer-events: auto;
transform:translate(-50%, -50%) scale(1);
}
/* start quiz button styling */
.start_btn1 button,
.start_btn2 button{
font-size: 25px;
font-weight: 500;
width:100%;
color: #0984e3;
/* margin:30px; */
padding: 15px 30px;
/* outline: 5px solid gray; */
outline: none;
/* border: 20px solid red; */
border: none;
border-radius: 5px;
background: #fff;
cursor: pointer;
}
.info_box{
width: 640px;
background: #fff;
border-radius: 5px;
opacity: 0;
pointer-events: none;
transform:translate(-50%, -50%) scale(0.9);
}
.info_box .info_title{
height: 60px;
width: 100%;
border-bottom: 1px solid lightgrey;
display: flex;
align-items: center;
/* justify-content: center; */
padding: 0px 30px;
font-size: 20px;
font-weight: 600;
}
.info_box .info_list{
padding: 15px 35px;
}
.info_box .info_list .info{
margin: 5px 0;
font-size: 17px;
}
.info_box .info_list .info span{
font-weight: 600;
color: #0984e3;
}
.info_box .buttons{
height:60px;
display: flex;
align-items: center;
justify-content: flex-end;
padding: 0 35px;
border-top: 1px solid lightgrey;
}
.info_box .buttons button{
margin: 0 5px;
height: 40px;
width: 100px;
outline: none;
border: 1px solid #0984e3;
border-radius: 5px;
color: #fff;
font-size: 16px;
font-weight: 500;
cursor: pointer;
transition: all 0.3s ease;
}
/* button quit 같은 위치 붙여쓰기 */
.buttons button.restart{
color: #fff;
background: #0984e3;
}
.buttons button.restart:hover{
background: #0770c0;
}
.buttons button.quit{
color: #0984e3;
border-color: #0984e3;
}
.buttons button.quit:hover{
color: #fff;
background: #0984e3;
}
.quiz_box{
width: 650px;
background: #fff;
border-radius: 5px;
opacity: 0;
pointer-events: none;
transform:translate(-50%, -50%) scale(0.9);
}
.quiz_box header{
position:relative;
z-index: 99;
height: 70px;
padding: 0 30px;
background: #fff;
display: flex;
align-items: center;
justify-content: space-between;
border-radius: 5px 5px 0 0;
box-shadow: 0px 3px 5px 1px rgba(0,0,0,0.1);
}
.quiz_box header .title{
font-size: 20px;
font-weight: 600;
}
.quiz_box header .timer{
display:flex;
align-items:center;
justify-content: space-between;
width: 145px;
height: 45px;
background: #cce5ff;
border: 1px solid #b8daff;
border-radius: 5px;
padding: 0 8px;
}
.quiz_box header .timer .time_text{
font-weight: 400;
font-size: 17px;
user-select:none;
/* 글자 선택 안됨 text 글자선택 가능 */
}
.quiz_box header .timer .timer_sec{
font-size: 18px;
font-weight: 500;
background: #5d5f5f;
height: 30px;
width: 45px;
color: #fff;
text-align: center;
line-height: 32px;
border-radius: 5px;
border:1px solid #5d5f5f;
user-select: none;
}
.quiz_box header .time_line{
position: absolute;
bottom: 0px;
left: 0px;
height: 3px;
background: #0984e3;
}
.quiz_box section{
padding: 25px 30px 20px 30px;
background:#fff;
}
.quiz_box section .que_text{
font-size: 25px;
font-weight: 600;
}
.quiz_box section .option_list,
section .word-input-box{
padding: 20px 0;
display: block;
}
section .option_list .option,
.word-input
{
background: aliceblue;
border: 1px solid #84c5fe;
border-radius: 5px;
padding: 8px 15px;
margin-bottom:15px;
font-size:17px;
display:flex;
align-items: center;
justify-content: space-between;
cursor:pointer;
transition: all 0.3s ease;
}
.word-input{
margin: 0;
outline:none;
}
.word-submit{
height:40px;
padding: 0 13px;
font-size:18px;
font-weight: 400;
border: none;
outline: none;
color:#fff;
background:#0984e3;
border-radius: 5px;
border: 1px solid #0984e3;
cursor:pointer;
transition:all 0.3s ease;
}
.audio_buttons .audio_btn1,
.audio_buttons .audio_btn2{
height:40px;
padding: 0 13px;
font-size:18px;
font-weight: 400;
border: none;
outline: none;
color:#fff;
background:#0984e3;
border-radius: 5px;
border: 1px solid #0984e3;
cursor:pointer;
transition:all 0.1s ease;
}
.word-submit:hover
{
background:#0770c0;
}
.audio_buttons .audio_btn1:active,
.audio_buttons .audio_btn2:active
{ transform: translate(1px, 1px);
}
.audio_buttons .audio_btn1{
width:110px;
background-color: #2e2d30;
border:none;
border-bottom:5px solid #5c5c5e;
margin: 19px 15px 10px 0;
display:flex;
align-items: center;
justify-content:space-between;
}
.audio_buttons .audio_btn2{
width:110px;
background-color: #f12929;
border:none;
border-bottom:5px solid #c9582b;
margin: 19px 15px 10px 0;
display: flex;
align-items: center;
justify-content: space-between;
}
.audio_buttons{
display:flex;
align-items: center;
}
section .word-input-box{
display:flex;
align-items: center;
justify-content: space-between;
margin-top: 30px;
}
section .word-input-box .word-input{
margin-right: 30px;
width: 80%;
}
section .msg{
font-size: 16px;
font-weight: 600;
margin: 10px 6px;
color:#0984e3;
/* display: none; */
}
section .option_list .option:hover{
color: #004085;
background: #cce5ff;
border-color: #b8daff;
}
/* :nth-last-child() */
.option_list .option:last-child{
margin-bottom: 0px;
}
.option_list .option .icon{
height: 26px;
width:26px;
border:2px solid transparent;
border-radius: 50%;
text-align:center;
font-size: 13px;
line-height: 24px;
pointer-events:none;
}
.option_list .option .icon.tick{
color: #23903c;
border-color:#23903c;
background:#d4edda;
}
.option_list .option .icon.cross{
color: #a42834;
background:#f8d7da;
border-color:#a42834;
}
.option_list .option.correct{
color: #155724;
border-color:#d4edda;
background:#c3e6cb;
}
.option_list .option.incorrect{
color: #721c24;
border-color:#f8d7da;
background:#f5c6cb;
}
.option_list .option.disabled,
.word-input-box.disabled
{
pointer-events: none;
}
.quiz_box footer{
height: 60px;
width: 100%;
padding: 0 30px;
display: flex;
align-items: center;
justify-content: space-between;
}
.quiz_box footer .total_que span{
display: flex;
user-select: none;
}
footer .total_que span p{
font-weight: 500;
padding: 0 5px;
}
.total_que span p:first-child{
padding-left: 0px;
}
footer .next_btn{
display: none;
height:40px;
padding: 0 13px;
font-size:18px;
font-weight: 400;
border: none;
outline: none;
color:#fff;
background:#0984e3;
border-radius: 5px;
border: 1px solid #0984e3;
cursor:pointer;
transition:all 0.3s ease;
}
footer .next_btn:hover{
background:#0770c0;
}
.result_box{
background:#fff;
width:450px;
padding: 25px 30px;
border-radius:5px;
display:flex;
text-align: center;
align-items: center;
flex-direction:column;
justify-content:space-between;
opacity: 0;
pointer-events: none;
transform:translate(-50%, -50%) scale(0.9);
}
.result_box .icon{
font-size: 100px;
color:#0984e3;
margin-bottom: 10px;
}
.result_box .complete_text{
font-size: 20px;
font-weight: 500;
}
.result_box .score_text span{
display:flex;
margin: 10px 0;
font-size:18px;
font-weight:500;
}
.score_text span p{
font-weight: 600;
padding: 0 4px;
}
.result_box .buttons{
display:flex;
margin: 20px 0;
}
.result_box .buttons button{
margin: 0 10px;
height: 45px;
padding: 0 20px;
border:none;
outline:none;
font-size:18px;
font-weight: 500;
border-radius:5px;
border:1px solid #0984e3;
cursor:pointer;
transition:all 0.3s ease;
}
js 폴더 만들고 파일 넣기
questions.js
//creating an array and passing the number, questions, options, and answers
let questions = [
{
numb: 1,
question: "Lorem ipsum, dolor sit amet consectetur adipisicing elit. Rerum vel soluta assumenda voluptatem aperiam modi vero excepturi, blanditiis corrupti quisquam?",
answer: "hodu",
options: [
"ninjin",
"yeojeee",
"yeojin",
"hodu"
]
},
{
numb: 2,
question: "Lorem ipsum, dolor sit amet consectetur adipisicing elit. Rerum vel soluta assumenda voluptatem aperiam modi vero excepturi, blanditiis corrupti quisquam?",
answer: "hodululu",
options: [
"ninjin",
"yeojeee",
"yeojin",
"hodululu"
]
},
{
numb: 3,
question: "Lorem ipsum, dolor sit amet consectetur adipisicing elit. Rerum vel soluta assumenda voluptatem aperiam modi vero excepturi, blanditiis corrupti quisquam?",
answer: "min",
options: [
"ninjin",
"yeojeee",
"yeojin",
"min"
]
},
{
numb: 4,
question: "Lorem ipsum, dolor sit amet consectetur adipisicing elit. Rerum vel soluta assumenda voluptatem aperiam modi vero excepturi, blanditiis corrupti quisquam?",
answer: "hoho",
options: [
"ninjin",
"yeojeee",
"yeojin",
"hoho"
]
},
{
numb: 5,
question: "Lorem ipsum, dolor sit amet consectetur adipisicing elit. Rerum vel soluta assumenda voluptatem aperiam modi vero excepturi, blanditiis corrupti quisquam?",
answer: "haha",
options: [
"ninjin",
"yeojeee",
"yeojin",
"haha"
]
}
]
questions2.js
//creating an array and passing the number, questions, options, and answers
let questions = [
{
numb: 1,
question: "Whaaaaaat is your name1?",
answer: "ninjin",
options: [
"ninjin",
"yeojeee",
"yeojin",
"hodu"
]
},
{
numb: 2,
question: "Whaaaaaaaat is your name2?",
answer: "ninjin",
options: [
"ninjin",
"yeojeee",
"yeojin",
"hodululu"
]
},
{
numb: 3,
question: "Whaaaaaaat is your name3?",
answer: "ninjin",
options: [
"ninjin",
"yeojeee",
"yeojin",
"min"
]
},
{
numb: 4,
question: "Whaaaaaaaaat is your name4?",
answer: "ninjin",
options: [
"ninjin",
"yeojeee",
"yeojin",
"hoho"
]
},
{
numb: 5,
question: "Whaaaaaaaaaat is your name5?",
answer: "ninjin",
options: [
"ninjin",
"yeojeee",
"yeojin",
"haha"
]
}
]
script.js
// getting all required elements
const start_btn1 = document.querySelector(".start_btn1 button");
const info_box = document.querySelector(".info_box");
const exit_btn = info_box.querySelector(".buttons .quit");
const continue_btn = info_box.querySelector(".buttons .restart");
const quiz_box = document.querySelector(".quiz_box");
const option_list = document.querySelector(".option_list");
const word_input_box = document.querySelector(".word-input-box");
const word_submit = quiz_box.querySelector(".word-submit");
const word_input = quiz_box.querySelector(".word-input");
const msg = quiz_box.querySelector(".msg");
const timeCount = quiz_box.querySelector(".timer .timer_sec");
const timeLine = quiz_box.querySelector("header .time_line");
const timeOff = quiz_box.querySelector("header .time_text");
// let audio_list = document.querySelector(".quiz_box .audio_list");
let audio_list = ['media/1.mp3','media/2.mp3','media/3.mp3','media/4.mp3','media/5.mp3'];
let audio = document.querySelector(".quiz_box .audio_list .audio");
let audio_buttons = document.querySelector(".quiz_box section .audio_buttons");
const playPauseBTN = document.querySelector(".quiz_box .audio_buttons .audio_btn1");
const stopBTN = document.querySelector(".quiz_box .audio_buttons .audio_btn2");
let iconPlay = '<div class="iconPlay"><i class="fas fa-play"></i></div>';
let iconPause = '<div class="iconPause"><i class="fas fa-pause"></i></div>';
let iconStop = '<div class="iconPause"><i class="fas fa-pause"></i></div>';
let audio_count = 0;
playPauseBTN.onclick = ()=>{
playPause();
}
stopBTN.onclick = ()=>{
stop();
}
function playPause(){
if(audio_count == 0){
audio_count = 1;
audio.src = audio_list[que_count];
audio.play();
playPauseBTN.innerHTML = 'Pause'+ iconPause;
}else{
audio_count = 0;
audio.src = audio_list[que_count];
audio.pause();
playPauseBTN.innerHTML = 'Play'+ iconPlay;
}
}
function stop(){
playPause();
audio.src = audio_list[que_count];
audio.pause();
audio.currentTime = 0;
playPauseBTN.innerHTML = 'Play'+ iconPlay;
}
function off(){
// document.querySelector(".quiz_box section .audio_buttons .audio_btn1").disabled = true;
playPauseBTN.disabled = true;
stopBTN.disabled = true;
audio.pause();
}
function on(){
playPauseBTN.disabled = false;
stopBTN.disabled = false;
playPauseBTN.innerHTML = 'Play'+ iconPlay;
}
// if start quiz button clicked
start_btn1.onclick = ()=>{
info_box.classList.add("activeInfo"); //show the info box
}
// if exit button clicked
exit_btn.onclick = ()=>{
info_box.classList.remove("activeInfo"); //hide the info box
window.location.href="index.html";
}
// if continue button clicked
continue_btn.onclick = ()=>{
info_box.classList.remove("activeInfo"); //hide the info box
quiz_box.classList.add("activeQuiz"); //show the quiz box
showQuestions2(0);
queCounter(1);
startTimer(15);
startTimerLine(0);
}
let que_count = 0;
let que_numb = 1;
let counter;
let counterLine;
let timeValue = 15;
let widthValue = 0;
let userScore = 0;
const next_btn = quiz_box.querySelector(".next_btn");
const result_box = document.querySelector(".result_box");
const restart_quiz = result_box.querySelector(".buttons .restart");
const quit_quiz = result_box.querySelector(".buttons .quit");
//실패 아래처럼 수정
restart_quiz.onclick = ()=>{
window.location.reload();
}
quit_quiz.onclick = ()=>{
window.location.href="index.html";
}
word_submit.onclick = ()=>{
if(que_count < questions.length ){
inputAns();
next_btn_value(que_count);
// que_count++;
// que_numb++;
// showQuestions2(que_count);
// queCounter(que_numb);
// startTimer(timeValue);
// startTimerLine(widthValue);
clearInterval(counterLine);
clearInterval(counter);
next_btn.style.display = "block";
word_input_box.classList.add("disabled");
off();
timeOff.textContent = "Time Left";
word_input.value="";
}
else{
// clearInterval(counter);
// clearInterval(counterLine);
console.log("Questions completed");
showResultBox();
}
}
next_btn.onclick = ()=>{
if(que_count < questions.length -1){
que_count++;
que_numb++;
showQuestions2(que_count);
on();
queCounter(que_numb);
clearInterval(counter);
startTimer(timeValue);
clearInterval(counterLine);
startTimerLine(widthValue);
next_btn.style.display = "none";
timeOff.textContent = "Time Left";
word_input.value="";
word_input_box.classList.remove("disabled");
msg.innerHTML = "Your answer is ..";
next_btn_value();
}
else{
// clearInterval(counter);
// clearInterval(counterLine);
console.log("Questions completed");
showResultBox();
}
}
function next_btn_value(index){
if(que_count < questions.length -1){
next_btn.innerHTML = "Next Que";
}else{
next_btn.innerHTML = "Go to Result";
}
}
function showQuestions2(index){
const que_text = document.querySelector(".que_text");
let que_tag = '<span>'+ questions[index].numb + ". " + questions[index].question +'</span>';
que_text.innerHTML = que_tag;
}
function inputAns(answer){
let correctAns = questions[que_count].answer;
console.log(correctAns);
if(word_input.value == correctAns){
msg.innerHTML = "correct!";
userScore += 1;
console.log(userScore);
console.log(correctAns);
console.log("Answer is Correct!");
}
else{
console.log("Answer is Wrong!");
msg.innerHTML = "wrong..!";
}
}
function showResultBox(){
info_box.classList.remove("activeInfo"); //hide the info box
quiz_box.classList.remove("activeQuiz"); //hide the quiz box
result_box.classList.add("activeResult"); //show the result box
const scoreText = result_box.querySelector(".score_text");
if(userScore > 3){
let scoreTag = '<span>and congrats! You got <p>'+ userScore +'</p> out of <p>'+ questions.length +'</p></span>';
scoreText.innerHTML = scoreTag;
}
else if(userScore > 1){
let scoreTag = '<span>and nice, You got <p>'+ userScore +'</p> out of <p>'+ questions.length +'</p></span>';
scoreText.innerHTML = scoreTag;
}
else{
let scoreTag = '<span>and sorry, You got <p>'+ userScore +'</p> out of <p>'+ questions.length +'</p></span>';
scoreText.innerHTML = scoreTag;
}
}
function startTimer(time){
counter = setInterval(timer, 1000);
function timer(){
timeCount.textContent = time;
time--;
if(time < 9){
let addZero = timeCount.textContent;
timeCount.textContent = "0" + addZero;
}
if(time < 0){
clearInterval(counter);
timeCount.textContent = "00";
timeOff.textContent = "Time Off";
word_input_box.classList.add("disabled");
next_btn.style.display = "block";
msg.innerHTML = "time's up!";
next_btn_value(que_count);
off();
}
}
}
//라인 속도25 너비648 조절 어려움
function startTimerLine(time){
counterLine= setInterval(timer, 25);
function timer(){
time += 1;
timeLine.style.width = time + "px";
// 박스 사이즈를 더 넓게 해서 조금 달라짐 549-->?
if(time > 648){
clearInterval(counterLine);
}
}
}
function queCounter(index){
const bottom_ques_counter = quiz_box.querySelector(".total_que");
let totalQuesCountTag = '<span><p>'+ index +'</p>of<p>'+ questions.length +'</p>Questions</span>';
bottom_ques_counter.innerHTML = totalQuesCountTag;
}
script2.js
// getting all required elements
const start_btn1 = document.querySelector(".start_btn1 button");
const info_box = document.querySelector(".info_box");
const exit_btn = info_box.querySelector(".buttons .quit");
const continue_btn = info_box.querySelector(".buttons .restart");
const quiz_box = document.querySelector(".quiz_box");
const option_list = document.querySelector(".option_list");
const word_input_box = document.querySelector(".word-input-box");
const word_submit = quiz_box.querySelector(".word-submit");
const word_input = quiz_box.querySelector(".word-input");
const timeCount = quiz_box.querySelector(".timer .timer_sec");
const timeLine = quiz_box.querySelector("header .time_line");
const timeOff = quiz_box.querySelector("header .time_text");
// if start quiz button clicked
start_btn1.onclick = ()=>{
info_box.classList.add("activeInfo"); //show the info box
}
// if exit button clicked
exit_btn.onclick = ()=>{
info_box.classList.remove("activeInfo"); //hide the info box
window.location.href="index.html";
}
// if continue button clicked
continue_btn.onclick = ()=>{
info_box.classList.remove("activeInfo"); //hide the info box
quiz_box.classList.add("activeQuiz"); //show the quiz box
showQuestions(0);
queCounter(1);
startTimer(15);
startTimerLine(0);
}
let que_count = 0;
let que_numb = 1;
let counter;
let counterLine;
let timeValue = 15;
let widthValue = 0;
let userScore = 0;
const next_btn = quiz_box.querySelector(".next_btn");
const result_box = document.querySelector(".result_box");
const restart_quiz = result_box.querySelector(".buttons .restart");
const quit_quiz = result_box.querySelector(".buttons .quit");
let correctAns = questions[que_count].answer;
console.log(correctAns);
/* 원본
restart_quiz.onclick = ()=>{
quiz_box.classList.add("activeQuiz");//show quiz box
result_box.classList.remove("activeResult");//hide result box
let que_count = 0;
let que_numb = 1;
let timeValue = 15;
let widthValue = 0;
let userScore = 0;
showQuestions(que_count); //calling showQestions function
queCounter(que_numb);//passing que_numb value to queCounter
clearInterval(counter);//clear counter
startTimer(timeValue);//calling startTimer function
clearInterval(counterLine);//clear counterLine
startTimerLine(widthValue);//calling startTimerLine function
next_btn.style.display = "none";//hide the next button
timeOff.textContent = "Time Left"; //change the text of timeText to Time Left(Time Off)
}*/
//실패 아래처럼 수정
restart_quiz.onclick = ()=>{
window.location.reload();
}
quit_quiz.onclick = ()=>{
window.location.href="index.html";
}
next_btn.onclick = ()=>{
if(que_count < questions.length -1){
que_count++;
que_numb++;
showQuestions(que_count);
queCounter(que_numb);
clearInterval(counter);
startTimer(timeValue);
clearInterval(counterLine);
startTimerLine(widthValue);
next_btn.style.display = "none";
timeOff.textContent = "Time Left";
}
else{
// clearInterval(counter);
// clearInterval(counterLine);
console.log("Questions completed");
showResultBox();
}
}
// getting questions and options from array
function showQuestions(index){
const que_text = document.querySelector(".que_text");
let que_tag = '<span>'+ questions[index].numb + ". " + questions[index].question +'</span>';
let option_tag = '<div class="option"><span>'+ questions[index].options[0] +'</span></div>'
+ '<div class="option"><span>'+ questions[index].options[1] +'</span></div>'
+ '<div class="option"><span>'+ questions[index].options[2] +'</span></div>'
+ '<div class="option"><span>'+ questions[index].options[3] +'</span></div>';
que_text.innerHTML = que_tag;
option_list.innerHTML = option_tag;
const option = option_list.querySelectorAll(".option");
for (let i = 0; i < option.length; i++){
option[i].setAttribute("onclick", "optionSelected(this)");
}
}
let tickIcon = '<div class="icon tick"><i class="fas fa-check"></i></div>';
let crossIcon = '<div class="icon cross"><i class="fas fa-times"></i></div>';
function optionSelected(answer){
clearInterval(counter);
clearInterval(counterLine);
let userAns = answer.textContent;
let correctAns = questions[que_count].answer;
let allOptions = option_list.children.length;
if(userAns == correctAns){
userScore += 1;
console.log(userScore);
answer.classList.add("correct");
console.log("Answer is Correct!");
answer.insertAdjacentHTML("beforeend", tickIcon);
}
else{
answer.classList.add("incorrect");
console.log("Answer is Wrong!");
answer.insertAdjacentHTML("beforeend", crossIcon);
//if answers is incorrect then automatically selected correct answer
for (let i = 0; i < allOptions; i++){
if(option_list.children[i].textContent == correctAns){
option_list.children[i].setAttribute("class", "option correct");
option_list.children[i].insertAdjacentHTML("beforeend", tickIcon);
}
}
}
//once user selected disabled all options
for (let i = 0; i < allOptions; i++){
option_list.children[i].classList.add("disabled");
}
next_btn.style.display = "block";
}
function showResultBox(){
info_box.classList.remove("activeInfo"); //hide the info box
quiz_box.classList.remove("activeQuiz"); //hide the quiz box
result_box.classList.add("activeResult"); //show the result box
const scoreText = result_box.querySelector(".score_text");
if(userScore > 3){
let scoreTag = '<span>and congrats! You got <p>'+ userScore +'</p> out of <p>'+ questions.length +'</p></span>';
scoreText.innerHTML = scoreTag;
}
else if(userScore > 1){
let scoreTag = '<span>and nice, You got <p>'+ userScore +'</p> out of <p>'+ questions.length +'</p></span>';
scoreText.innerHTML = scoreTag;
}
else{
let scoreTag = '<span>and sorry, You got <p>'+ userScore +'</p> out of <p>'+ questions.length +'</p></span>';
scoreText.innerHTML = scoreTag;
}
}
function startTimer(time){
counter = setInterval(timer, 1000);
function timer(){
timeCount.textContent = time;
time--;
if(time < 9){
let addZero = timeCount.textContent;
timeCount.textContent = "0" + addZero;
}
if(time < 0){
clearInterval(counter);
timeCount.textContent = "00";
timeOff.textContent = "Time Off";
let correctAns = questions[que_count].answer;
let allOptions = option_list.children.length;
for (let i = 0; i < allOptions; i++){
if(option_list.children[i].textContent == correctAns){
option_list.children[i].setAttribute("class", "option correct");
option_list.children[i].insertAdjacentHTML("beforeend", tickIcon);
}
}
for (let i = 0; i < allOptions; i++){
option_list.children[i].classList.add("disabled");
}
next_btn.style.display = "block";
}
}
}
//라인 속도25 너비648 조절 어려움
function startTimerLine(time){
counterLine= setInterval(timer, 25);
function timer(){
time += 1;
timeLine.style.width = time + "px";
// 박스 사이즈를 더 넓게 해서 조금 달라짐 549-->?
if(time > 648){
clearInterval(counterLine);
}
}
}
function queCounter(index){
const bottom_ques_counter = quiz_box.querySelector(".total_que");
let totalQuesCountTag = '<span><p>'+ index +'</p>of<p>'+ questions.length +'</p>Questions</span>';
bottom_ques_counter.innerHTML = totalQuesCountTag;
}
온라인 퀴즈앱 뮤직 플레이어 만들기 마지막은 갖고 있는 음악 파일을 media 폴더에 저장하고 js 폴더와 나란히 위치시키면 된다.
1.html 에서 <source src="media/1.mp3" type="audio/mpeg"> 이런식으로 불러오면 된다.
이렇게 Quiz App 만들기는 일단락 되었다.
다음 시간에는 영어 바닐라 타자 게임을 만들어 보려고 한다.
그럼 오늘도 열공하자!

To be continued...
(인스타툰, 텀블러, 유리컵, 그립톡, 폰케이스, 슬리퍼 등)
hodululu | 인포크링크
hodululu님의 멀티링크를 구경해보세요 👀
link.inpock.co.kr
'코딩 공부 + IT 정보 > 코딩 실험' 카테고리의 다른 글
티스토리 스킨 편집 2탄, 구글 노출용 포스팅은 따로 있었다! (0) | 2021.08.04 |
---|---|
타자 게임 만들고 영어, 스페인어 공부해보자 (Vanilla JavaScript Speed Typing Game) (0) | 2021.07.29 |
코딩 자격증 없이 온라인 퀴즈앱 만들기 - 두번째 이야기(short-answer question quiz app) (0) | 2021.07.23 |
티스토리 스킨 편집하기(글씨체, 가운데 정렬, scroll top button 등등) (0) | 2021.07.22 |
코딩 자격증 없이 온라인 퀴즈앱 만들기 - 첫번째 이야기(multiple choice quiz app) (0) | 2021.07.21 |