728x90
반응형
주관식 여러문제 확인하기 유형 퀴즈 이펙트
수업 시간에 배운 내용을 복습하면서 해보겠습니다.
코드 보기(HTML, JAVASCRIPT / CSS1 / CSS2) / 완성화면
HTML
<!DOCTYPE html>
<html lang="ko">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>퀴즈 이펙트03</title>
<link rel="stylesheet" href="css/reset.css">
<link rel="stylesheet" href="css/quiz.css">
</head>
<body>
<header id="header">
<h1><a href="../javascript14.html">Quiz</a> <em>주관식 확인하기(여러문제) 유형</em></h1>
<ul>
<li><a href="quizEffect01.html">1</a></li>
<li><a href="quizEffect02.html">2</a></li>
<li class="active"><a href="quizEffect03.html">3</a></li>
<li><a href="quizEffect04.html">4</a></li>
</ul>
</header>
<!-- //header -->
<main id="main">
<div class="quiz__wrap">
<div class="quiz">
<div class="quiz__header">
<h2 class="quiz__title"></h2>
</div>
<div class="quiz__main">
<div class="quiz__question">
<em></em>. <span></span>
</div>
<div class="quiz__view">
<div class="dog__wrap">
<div class="true">정답입니다!</div>
<div class="false">틀렸습니다!</div>
<div class="card-container">
<div class="dog">
<div class="head">
<div class="ears"></div>
<div class="face"></div>
<div class="eyes">
<div class="teardrop"></div>
</div>
<div class="nose"></div>
<div class="mouth">
<div class="tongue"></div>
</div>
<div class="chin"></div>
</div>
<div class="body">
<div class="tail"></div>
<div class="legs"></div>
</div>
</div>
</div>
</div>
</div>
<div class="quiz__answer">
<input class="input" type="text" placeholder="정답을 적어주세요!">
<button class="confirm">정답 확인하기</button>
<div class="result"></div>
</div>
<div class="quiz__desc"></div>
</div>
</div>
<div class="quiz">
<div class="quiz__header">
<h2 class="quiz__title"></h2>
</div>
<div class="quiz__main">
<div class="quiz__question">
<em></em>. <span></span>
</div>
<div class="quiz__view">
<div class="dog__wrap">
<div class="true">정답입니다!</div>
<div class="false">틀렸습니다!</div>
<div class="card-container">
<div class="dog">
<div class="head">
<div class="ears"></div>
<div class="face"></div>
<div class="eyes">
<div class="teardrop"></div>
</div>
<div class="nose"></div>
<div class="mouth">
<div class="tongue"></div>
</div>
<div class="chin"></div>
</div>
<div class="body">
<div class="tail"></div>
<div class="legs"></div>
</div>
</div>
</div>
</div>
</div>
<div class="quiz__answer">
<input class="input" type="text" placeholder="정답을 적어주세요!">
<button class="confirm">정답 확인하기</button>
<div class="result"></div>
</div>
<div class="quiz__desc"></div>
</div>
</div>
<div class="quiz">
<div class="quiz__header">
<h2 class="quiz__title"></h2>
</div>
<div class="quiz__main">
<div class="quiz__question">
<em></em>. <span></span>
</div>
<div class="quiz__view">
<div class="dog__wrap">
<div class="true">정답입니다!</div>
<div class="false">틀렸습니다!</div>
<div class="card-container">
<div class="dog">
<div class="head">
<div class="ears"></div>
<div class="face"></div>
<div class="eyes">
<div class="teardrop"></div>
</div>
<div class="nose"></div>
<div class="mouth">
<div class="tongue"></div>
</div>
<div class="chin"></div>
</div>
<div class="body">
<div class="tail"></div>
<div class="legs"></div>
</div>
</div>
</div>
</div>
</div>
<div class="quiz__answer">
<input class="input" type="text" placeholder="정답을 적어주세요!">
<button class="confirm">정답 확인하기</button>
<div class="result"></div>
</div>
<div class="quiz__desc"></div>
</div>
</div>
</div>
</main>
<!-- //main -->
<footer id="footer">
<a href="mailto:dongjin6539@naver.com">dongjin6539@naver.com</a>
</footer>
<!-- //footer -->
</body>
</html>
HTML 구성
- body 태그에 알맞은 header 구역, main 구역, footer 구역을 만들어줍니다.
- header 구역에 h1 태그를 사용해 알맞은 제목을 입력해줍니다.
- footer 구역에 a 링크 태그를 사용해 받을 이메일 주소를 링크와 같이 입력해줍니다.
- main 구역에 각 자식의 자식 태그를 알맞게 만들어주고 각 class 명을 입력해줍니다.
- 주관식이므로 사용자가 답을 적을 수 있도록 input 태그를 사용해 만들어줍니다.
- 답에 대한 설명을 적기 위해 알맞은 class 명을 사용해 입력해줍니다.
- 여러 문제를 만들기 위해 "quiz__wrap" class에 자식으로 비슷한 형식의 문제를 자식으로 만들어줍니다.
- 강아지 이미지는 인터넷을 통해 얻어왔습니다. (참조: https://wsss.tistory.com/913)
- 위 페이지에 들어가서 코드펜을 통해 html 구조를 가져와서 main 구역에 입력해줍니다.(css 구조는 css 파일에 입력했습니다.)
- 그러면 body 태그의 구조는 완성됩니다.
- CSS는 각 태그에 알맞는 속성을 입력하고 속성 값을 입력해줍니다.
CSS1
/* header */
#header {
position: fixed;
left: 0;
top: 0;
background-color: #0243f1;
color: #fff;
padding: 10px;
width: 100%;
z-index: 1000;
display: flex;
justify-content: space-between;
}
#header::before {
content: '';
border: 4px ridge #00f7ff55;
position: absolute;
left: 5px;
top: 5px;
width: calc(100% - 10px);
height: calc(100% - 10px);
}
#header h1 {
font-size: 28px;
padding: 5px 5px 5px 10px;
font-family: 'DungGeunMo';
z-index: 10;
position: relative;
}
#header h1 a {
color: #fff;
}
#header h1 em {
font-size: 0.5em;
}
#header ul {
padding: 5px;
}
#header li {
display: inline;
z-index: 10;
position: relative;
}
#header li a {
color: #fff;
font-family: 'DungGeunMo';
border: 1px dashed #fff;
display: inline-block;
padding: 5px;
}
#header li.active a,
#header li a:hover {
background-color: #fff;
color: #000;
}
/* footer */
#footer {
position: fixed;
left: 0;
bottom: 0;
width: 100%;
background-color: #0243f1;
text-align: center;
}
#footer a {
color: #fff;
padding: 20px;
display: block;
font-family: 'DungGeunMo';
z-index: 10;
position: relative;
}
#footer::before {
content: '';
border: 4px ridge #00f7ff55;
position: absolute;
left: 5px;
top: 5px;
width: calc(100% - 10px);
height: calc(100% - 10px);
}
#main {
padding: 100px 0;
}
/* quiz__wrap */
.quiz__wrap {
display: flex;
justify-content: center;
flex-wrap: wrap;
align-items: flex-start;
}
.quiz__wrap .quiz {
width: 500px;
background-color: #fff;
border: 8px ridge #0243f1;
margin: 10px;
}
.quiz__title {
background-color: #0243f1;
border: 3px ridge #00f7ff55;
border-bottom-width: 6px;
padding: 5px;
font-family: 'DungGeunMo';
font-size: 16px;
color: #fff;
text-align: center;
}
.quiz__question {
padding: 20px;
font-size: 24px;
font-family: 'PyeongChang';
font-weight: 300;
line-height: 1.4;
border-bottom: 6px ridge #0243f1;
}
.quiz__question em {
color: #0243f1;
}
.quiz__answer {
font-family: 'PyeongChang';
padding: 20px;
text-align: center;
font-size: 24px;
}
.quiz__answer .confirm {
color: #fff;
background-color: #0243f1;
border: 6px ridge #0243f1;
width: 100%;
font-family: 'PyeongChang';
padding: 10px 20px;
font-size: 22px;
cursor: pointer;
transition: all 0.3s;
font-weight: bold;
}
.quiz__answer .confirm:hover {
color: #000;
background-color: #0243f155;
}
.quiz__answer .result {
background-color: #0243f155;
border: 6px ridge #0243f1;
width: 100%;
font-family: 'PyeongChang';
padding: 10px 20px;
font-size: 22px;
}
.quiz__answer .input {
background-color: #fff;
border: 6px groove #0243f1;
width: 100%;
font-family: 'PyeongChang';
padding: 10px 20px;
font-size: 22px;
margin-bottom: 10px;
}
.quiz__view {
border-bottom: 6px ridge #0243f1;
overflow: hidden;
}
.quiz__desc {
border-top: 6px ridge #0243f1;
padding: 20px;
font-family: 'PyeongChang';
background-color: #0243f155;
}
.quiz__desc::before {
content: '✍️ Tip ';
color: #ff3c3c;
font-weight: bold;
}
.quiz__choice {
padding: 20px;
border-bottom: 6px ridge #0243f1;
font-family: 'PyeongChang';
}
.quiz__choice label {
display: flex;
}
.quiz__choice label input {
position: absolute;
clip: rect(0 0 0 0);
width: 1px;
height: 1px;
margin: -1px;
overflow: hidden;
}
.quiz__choice label span {
font-size: 20px;
line-height: 1.4;
padding: 6px;
display: flex;
cursor: pointer;
margin: 2px 0;
}
.quiz__choice label span::before {
content: '';
width: 26px;
height: 26px;
border-radius: 50%;
background: #fff;
box-shadow: inset 0 0 0 4px #0243f1;
margin-right: 15px;
transition: all 0.2s;
}
.quiz__choice label input:checked + span {
background-color: #0243f155;
}
.quiz__choice label input:checked + span::before {
box-shadow: inset 0 0 0 8px #0243f1;
}
CSS2
@import url('https://webfontworld.github.io/DungGeunMo/DungGeunMo.css');
@import url('https://webfontworld.github.io/PyeongChang/PyeongChang.css');
* {
margin: 0;
padding: 0;
}
*, *::before, *::after {
box-sizing: border-box;
}
a {
text-decoration: none;
color: #222;
}
h1, h2, h3, h4, h5, h6 {
font-weight: normal;
}
li, ul, ol {
list-style: none;
}
img {
vertical-align: top;
width: 100%;
}
em {
font-style: normal;
}
body {
background:
radial-gradient(#0243f1 3px, transparent 4px),
radial-gradient(#0243f1 3px, transparent 4px),
linear-gradient(#fff 4px, transparent 0),
linear-gradient(45deg, transparent 74px, transparent 75px, #00f7ff 75px, #00f7ff 76px, transparent 77px, transparent 109px),
linear-gradient(-45deg, transparent 75px, transparent 76px, #00f7ff 76px, #00f7ff 77px, transparent 78px, transparent 109px),
#fff;
background-size: 109px 109px, 109px 109px, 100% 6px, 109px 109px, 109px 109px;
background-position: 54px 55px, 0px 0px, 0px 0px, 0px 0px, 0px 0px;
}
JAVASCRIPT
<script>
// 선택자
const quizWrap = document.querySelector(".quiz__wrap");
const quizTitle = quizWrap.querySelectorAll(".quiz__title"); // 문제 종목 / 문제 시간
const quizQusetionNum = quizWrap.querySelectorAll(".quiz__question em"); // 문제 번호
const quizQuestion = quizWrap.querySelectorAll(".quiz__question span"); // 문제 질문
const quizAnswerResult = quizWrap.querySelectorAll(".quiz__answer .result"); // 문제 정답
const quizDesc = quizWrap.querySelectorAll(".quiz__desc"); // 문제 해설
const quizAnswerCofirm = quizWrap.querySelectorAll(".quiz__answer .confirm"); // 정답 버튼
const quizAnswerInput = quizWrap.querySelectorAll(".quiz__answer .input"); // 사용자 정답
const dogWrap = quizWrap.querySelectorAll(".dog__wrap");
// 문제 정보
const quizInfo = [
{
infoType: "정보처리 기능사",
infoTime: "2011년 4회",
infoNumber: "1",
infoQuestion: "주파수분할 다중화 방식에서 각 채널간 간섭을 막기 위해서 일종의 완충지역 역할을 하는 것은?",
infoAnswer: "가드밴드",
infoDesc: "가드밴드(Guard Band)는 주파수분할 다중화 방식에서 각 채널간 간섭을 막기 위해서 일종의 완충지역 역할을 합니다."
},{
infoType: "정보처리 기능사",
infoTime: "2011년 4회",
infoNumber: "2",
infoQuestion: "사용자의 명령으로 시스템이 수행되고 그에 따른 결과를 나타내 주는 대화식 운영체제는 무엇인가?",
infoAnswer: "UNIX",
infoDesc: "UNIX는 사용자의 명령으로 시스템이 수행되고 그에 따른 결과를 나타내 주는 대화식 운영체제입니다."
},{
infoType: "정보처리 기능사",
infoTime: "2011년 4회",
infoNumber: "3",
infoQuestion: "프로세스들이 서로 다른 프로세스가 차지하고 있는 자원을 무한정 기다려 시스템이 멈춘 것처럼 보이는 상태를 무엇이라고 하는가?",
infoAnswer: "교착상태",
infoDesc: "교착상태(Deadlock)는 2개 이상의 프로세스들이 서로 다른 프로세스가 차지하고 있는 자원을 무한정 기다려 시스템이 멈춘 것처럼 보이는 상태입니다."
}
];
// #1
// 문제 종류
// quizTitle[0].textContent = quizInfo[0].infoType;
// quizTitle[1].textContent = quizInfo[1].infoType;
// quizTitle[2].textContent = quizInfo[2].infoType;
// 문제 시간
// quizTime[0].textContent = quizInfo[0].infoTime;
// quizTime[1].textContent = quizInfo[1].infoTime;
// quizTime[2].textContent = quizInfo[2].infoTime;
// 문제 번호
// quizQusetionNum[0].textContent = quizInfo[0].infoNumber;
// quizQusetionNum[1].textContent = quizInfo[1].infoNumber;
// quizQusetionNum[2].textContent = quizInfo[2].infoNumber;
// 문제 질문
// quizQuestion[0].textContent = quizInfo[0].infoQuestion;
// quizQuestion[1].textContent = quizInfo[1].infoQuestion;
// quizQuestion[2].textContent = quizInfo[2].infoQuestion;
// 문제 정답
// quizAnswerResult[0].textContent = quizInfo[0].infoAnswer;
// quizAnswerResult[1].textContent = quizInfo[1].infoAnswer;
// quizAnswerResult[2].textContent = quizInfo[2].infoAnswer;
// 문제 해설
// quizDesc[0].textContent = quizInfo[0].infoDesc;
// quizDesc[1].textContent = quizInfo[1].infoDesc;
// quizDesc[2].textContent = quizInfo[2].infoDesc;
// #2
// 문제 종류 + 문제 시간
// quizTitle[0].innerHTML = quizInfo[0].infoType + " " + quizInfo[0].infoTime;
// quizTitle[1].innerHTML = quizInfo[1].infoType + " " + quizInfo[1].infoTime;
// quizTitle[2].innerHTML = quizInfo[2].infoType + " " + quizInfo[2].infoTime;
// 문제 번호
// quizQusetionNum[0].textContent = quizInfo[0].infoNumber;
// quizQusetionNum[1].textContent = quizInfo[1].infoNumber;
// quizQusetionNum[2].textContent = quizInfo[2].infoNumber;
// 문제 질문
// quizQuestion[0].textContent = quizInfo[0].infoQuestion;
// quizQuestion[1].textContent = quizInfo[1].infoQuestion;
// quizQuestion[2].textContent = quizInfo[2].infoQuestion;
// for(let i=0; i<quizInfo.length; i++){
// quizTitle[i].innerHTML = quizInfo[i].infoType + " " + quizInfo[i].infoTime;
// quizQusetionNum[i].textContent = quizInfo[i].infoNumber;
// quizQuestion[i].textContent = quizInfo[i].infoQuestion;
// quizAnswerResult[i].textContent = quizInfo[i].infoAnswer;
// quizDesc[i].textContent = quizInfo[i].infoDesc;
// };
quizInfo.forEach(function(el, i){
quizTitle[i].innerHTML = quizInfo[i].infoType + " " + quizInfo[i].infoTime;
quizQusetionNum[i].textContent = quizInfo[i].infoNumber;
quizQuestion[i].textContent = quizInfo[i].infoQuestion;
quizAnswerResult[i].textContent = quizInfo[i].infoAnswer;
quizDesc[i].textContent = quizInfo[i].infoDesc;
});
// 정답 숨기기 + 해설 숨기기
// quizAnswerResult[0].style.display = "none";
// quizAnswerResult[1].style.display = "none";
// quizAnswerResult[2].style.display = "none";
// quizDesc[0].style.display = "none";
// quizDesc[1].style.display = "none";
// quizDesc[2].style.display = "none";
// for(let i=0; i<quizInfo.length; i++){
// quizAnswerResult[i].style.display = "none";
// quizDesc[i].style.display = "none";
// };
quizInfo.forEach(function(el, i){
quizAnswerResult[i].style.display = "none";
quizDesc[i].style.display = "none";
});
// 정답 확인
quizAnswerCofirm.forEach(function(btn, num){
btn.addEventListener("click", function(){
// 사용자 정답
const userAnswer = quizAnswerInput[num].value;
quizAnswerCofirm[num].style.display = "none"; // 정답 확인 버튼 숨김
quizAnswerResult[num].style.display = "block"; // 정답 보이기
quizDesc[num].style.display = "block"; // 해설 보이기
// 사용자 정답 == 문제 정답
if(userAnswer == quizInfo[num].infoAnswer){
quizAnswerInput[num].style.display = "none"; // 답 입력창 숨기기
dogWrap[num].classList.add("like");
} else {
dogWrap[num].classList.add("dislike");
}
});
});
</script>
자바스크립트 이용
- 위의 html body 구조는 반복해서 사용 될 수도 있어 script를 이용해 글씨를 입력해줍니다.
- 선택자로 변수를 지정해주고 지정한 변수가 여러 개가 있기 때문에 document.querySelectorAll 사용해서 선택자를 만들어주고 ( ) 안에 html body 태그의 입력하고자 하는 위치의 class 명과 태그를 입력해줍니다.
- 문제 정보를 변수 지정해주고 문제의 종류가 많기 때문에 배열 안에 객체가 있는 형식으로 각 구역에 맞는 알맞은 값을 입력해줍니다.
- 다양한 방법으로 문제의 정보를 출력해보겠습니다.
- #1 방법은 .textContent를 사용해서 정보가 배열 안에 객체가 있으니 배열 안에 객체가 있는 데이터를 불러오는 방법을 사용해서 문제의 정보를 출력했습니다.
- #2 방법은 문제의 종목과 시간의 변수를 하나로 묶어 .innerHTML을 사용해 위의 방법으로 데이터를 불러오고 중간에 띄어쓰기를 하기 위해 빈 문자열(" ")을 입력했습니다.
- 다음 계속 입력해보니 배열의 숫자를 계속 입력하기 때문에 for문을 사용해서 문제의 정보를 입력해보고 for문을 forEach( )로 바꿀 수 있으니 바꿔서 출력했습니다.
- forEach( )는 값(element), 인덱스(index), 배열(array)를 가져올 수 있는데 이번에는 인덱스를 가지고 오기 위해서 함수 인자를 인덱스 하나만 적으면 값의 인자로 알고 가져오기 때문에 el, i를 인자값으로 같이 입력해주고 for문에서 입력했던 형식의 실행문을 입력해줍니다.
- 정답 숨기기와 해설 숨기기도 위와 같은 방식으로 입력해줍니다.
- forEach( )를 사용해 사용자가 입력한 답과 정답을 출력해줍니다. 인자값을 btn, num으로 값과 인덱스를 줍니다.
- 사용자가 답을 입력하고 '정답 확인하기' 버튼을 클릭했을 때 정답이 나오면 버튼을 사라지게 하기 위해서 맞는 선택자를 가져오고 .addEventListener 속성을 가져와서 함수를 이용해 각 선택자의 변수가 나타나거나 사라지는 알맞은 스타일 속성을 입력해줍니다.
- 문제가 여러 개이기 때문에 사용자의 답을 여러 개 입력해야하는데 forEach( )의 인덱스를 가져오면 되서 'const userAnswer = quizAnswerInput[num].value;'를 입력해줍니다.
- 정답 확인버튼 숨기기, 정답 보이기, 해설 보이기를 forEach( )의 인덱스를 가져와 style을 입력해줍니다.
- 정답일 때와 오답일 때에 서로 다른 상황을 주기 위해서 if문을 사용해 조건식을 입력하고 그 상황에 맞게 알맞는 스타일을 주기 위해서 classList.add를 사용해줍니다.
- 그러면 정답과 오답을 입력했을 때 서로 다른 상황이 나옵니다.
참고
- 아직 잘 모르는 자바스크립트 속성에 대해 알아보겠습니다.(https://developer.mozilla.org/en-US/)
속성 | 속성 설명 |
innerHTML | 요소(element) 내에 포함 된 HTML 또는 XML 마크업을 가져오거나 설정합니다. |
forEach( ) | 주어진 함수를 배열 요소 각각에 대해 실행합니다. forEach( )는 element(값), index(인덱스), array(배열)을 불어오는 특징이 있습니다. |
document.querySelectorAll |
지정된 선택기 그룹과 일치하는 문서 요소 목록을 나타내 반환합니다. |
728x90
반응형