코딩 공부/JAVASCRIPT

퀴즈(Quiz) 사이트(7) - 보충의 보충

천서리 2023. 4. 5. 19:45
QUOTE THE DAY

“ 당신이 6개월 이상 한 번도 보지 않은 코드는 다른 사람이 다시 만드는 게 훨씬 더 나을 수 있다. ”

- 이글슨 (Eagleson)
반응형

자바스크립트 퀴즈(Quiz) 사이트 만들기 

이번에 만들어 본 퀴즈 사이트는 CBT 유형입니다.

전에 올린 퀴즈 사이트(7-1)에서 조금 보충한 내용들을 정리해보겠습니다.

 

 

 


퀴즈 사이트 추가 코드

 

<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="gineungsaJC2005_04">정보처리기능사 2005년 4회</option>
                <option value="gineungsaJC2005_05">정보처리기능사 2005년 5회</option>
                <option value="gineungsaJC2006_01">정보처리기능사 2006년 1회</option>
                <option value="gineungsaJC2006_02">정보처리기능사 2006년 2회</option>
                <option value="gineungsaJC2006_03">정보처리기능사 2006년 3회</option>
                <option value="gineungsaJC2006_05">정보처리기능사 2006년 5회</option>
                <option value="gineungsaJC2007_01">정보처리기능사 2007년 1회</option>
                <option value="gineungsaJC2007_02">정보처리기능사 2007년 2회</option>
                <option value="gineungsaJC2007_04">정보처리기능사 2007년 4회</option>
                <option value="gineungsaJC2007_05">정보처리기능사 2007년 5회</option>
                <option value="gineungsaJC2008_01">정보처리기능사 2008년 1회</option>
                <option value="gineungsaJC2008_02">정보처리기능사 2008년 2회</option>
                <option value="gineungsaJC2008_04">정보처리기능사 2008년 4회</option>
                <option value="gineungsaJC2008_05">정보처리기능사 2008년 5회</option>
                <option value="gineungsaJC2009_01">정보처리기능사 2009년 1회</option>
                <option value="gineungsaJC2009_05">정보처리기능사 2009년 5회</option>
                <option value="gineungsaJC2010_02">정보처리기능사 2010년 2회</option>
                <option value="gineungsaJC2010_05">정보처리기능사 2010년 5회</option>
                <option value="gineungsaJC2011_01">정보처리기능사 2011년 1회</option>
                <option value="gineungsaJC2011_02">정보처리기능사 2011년 2회</option>
                <option value="gineungsaJC2011_04">정보처리기능사 2011년 4회</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="gineungsaWD2010_01">웹디자인기능사 2010년 1회</option>
                <option value="gineungsaWD2010_02">웹디자인기능사 2010년 2회</option>
                <option value="gineungsaWD2010_04">웹디자인기능사 2010년 4회</option>
                <option value="gineungsaWD2010_05">웹디자인기능사 2010년 5회</option>
                <option value="gineungsaWD2011_01">웹디자인기능사 2011년 1회</option>
                <option value="gineungsaWD2011_02">웹디자인기능사 2011년 2회</option>
                <option value="gineungsaWD2011_04">웹디자인기능사 2011년 4회</option>
                <option value="gineungsaWD2011_05">웹디자인기능사 2011년 5회</option>
                <option value="gineungsaWD2012_02">웹디자인기능사 2012년 2회</option>
                <option value="gineungsaWD2012_04">웹디자인기능사 2012년 4회</option>
                <option value="gineungsaWD2012_05">웹디자인기능사 2012년 5회</option>
                <option value="gineungsaWD2013_02">웹디자인기능사 2013년 2회</option>
                <option value="gineungsaWD2013_04">웹디자인기능사 2013년 4회</option>
                <option value="gineungsaWD2013_05">웹디자인기능사 2013년 5회</option>
                <option value="gineungsaWD2014_01">웹디자인기능사 2014년 1회</option>
                <option value="gineungsaWD2014_04">웹디자인기능사 2014년 4회</option>
                <option value="gineungsaWD2014_05">웹디자인기능사 2014년 5회</option>
                <option value="gineungsaWD2015_01">웹디자인기능사 2015년 1회</option>
                <option value="gineungsaWD2015_03">웹디자인기능사 2015년 3회</option>
                <option value="gineungsaWD2015_04">웹디자인기능사 2015년 4회</option>
                <option value="gineungsaWD2015_05">웹디자인기능사 2015년 5회</option>
                <option value="gineungsaWD2016_01">웹디자인기능사 2016년 1회</option>
                <option value="gineungsaWD2016_04">웹디자인기능사 2016년 4회</option>
            </select>
        </div>
        <div class="cbt__view">
            당신의 이름은 <input type="text" class="name"> 입니다.<br>
            당신은 <span class="subject">웹디자인 기능사시험</span>을 선택했습니다.
        </div>
        <!-- <button class="minimal">시작하기</button> -->
        <button class="cbt__start__btn">시작하기</button>
    </div>
</div>

 

 

div 태그를 사용하여 시험자의 이름과 선택한 시험 항목을 보여주는 영역을 만들었습니다. 이름은 input 태그를 사용하여 입력할 수 있도록 하였습니다.

 

그리고 button 태그를 사용하여 "시작하기" 버튼을 만들어 시험을 시작할 수 있도록 하였습니다. 이 버튼을 클릭했을 때 시험을 시작하는 동작을 구현할 수 있습니다.

 

 

const cbtViewSubject = document.querySelector(".cbt__view .subject");
const cbtHeader = document.querySelector(".cbt__header h2");
const cbtStartBtn = document.querySelector(".cbt__start__btn");
const cbtStart = document.querySelector(".cbt__start");
const cbtTime = document.querySelector(".cbt__time");
const cbtEndScore = document.querySelector(".cbt__end__score")
const cbtName = document.querySelector(".cbt__name");
const yourName = document.querySelector(".cbt__view .name");

 

 

새로 만들어준 선택자 입니다.

 

 

let questionTime = "";
let questionTimeRemain = "3600";
let quizScore = 0;  // 현재 점수

//시작하기
const startQuiz = () => {
    cbtStart.classList.add("hide"); //모달창 제거

    //시간 설정
    questionTime = setInterval(reduceTime, 1000);

    //입력 이름 나오게
    cbtName.innerHTML = `${yourName.value}`
}

 

첫 번째 줄에서는 questionTime 변수를 빈 문자열로 초기화하고, questionTimeRemain 변수를 "3600"으로 초기화합니다. quizScore 변수는 0으로 초기화됩니다.

 

다음으로 startQuiz 함수가 정의됩니다. 이 함수는 퀴즈를 시작하는 역할을 합니다.

 

cbtStart 요소의 classListhide 클래스를 추가하여 모달 창을 숨기는 것으로 시작합니다.

 

그 다음, setInterval 함수를 사용하여 reduceTime 함수를 1초마다 실행하도록 questionTime 변수를 설정합니다. 이 함수는 시험 시간을 감소시키는 역할을 합니다.

 

마지막으로, cbtName 요소의 내용을 입력한 이름으로 변경합니다. 이렇게 함으로써 이름이 퀴즈 화면에 나타나게 됩니다.

 

 

//설명 없는거 제거
document.querySelectorAll(".cbt__question__desc").forEach(desc => {
    if(desc.innerText === "undefined"){
        desc.classList.add("hide");
    }
});

//이미지가 없는거 제거-
document.querySelectorAll(".cbt__question__img").forEach(img => {
    let src = img.querySelector("img").src;

    if(src.includes("undefined")){
        img.classList.add("hide");
    }
});

//점수 표시
document.querySelector(".cbt__submit").addEventListener("click", () => {
document.querySelector(".cbt__end__score").innerHTML = Math.ceil((quizScore / questionLength) * 100);
});

 

  1. 첫 번째 블록은 "cbt__question__desc" 클래스를 가진 요소들을 선택하고, 이들의 텍스트 내용이 "undefined"인 경우 "hide" 클래스를 추가하여 화면에서 해당 요소를 숨기는 기능입니다.
  2. 두 번째 블록은 "cbt__question__img" 클래스를 가진 요소들을 선택하고, 이들의 자식 요소 중 "img" 태그의 "src" 속성값이 "undefined"인 경우 "hide" 클래스를 추가하여 화면에서 해당 요소를 숨기는 기능입니다.
  3. 마지막 블록은 "cbt__submit" 클래스를 가진 버튼이 클릭될 때, 시험 점수를 계산하여 "cbt__end__score" 클래스를 가진 요소에 해당 점수를 표시하는 기능입니다.

위 코드를 통해 CBT 페이지에서 문제 내용이나 이미지가 없는 경우, 해당 요소를 화면에서 숨기고, 시험을 마치면 점수를 표시하는 기능을 구현할 수 있습니다.

 

 

 //시간 설정
const reduceTime = () => {
    questionTimeRemain--;

    if(questionTimeRemain == 0) endQuiz();

    cbtTime.innerText = displayTime();
}

//시간 표시
const displayTime = () => {
    if(questionTimeRemain <= 0){
        return "0분 00초";  //종료 의미, 결과 의미
    } else {
        let minutes = Math.floor(questionTimeRemain / 60);
        let seconds = questionTimeRemain % 60;

        //초의 단위가 한자리 수가 되면 앞에 0을 붙여주기
        if(seconds <= 9){
            seconds = "0"+seconds
        }
        return minutes + "분 " + seconds + "초";
    }
}

 

  1. 첫 번째 함수인 reduceTime은 시험 시간을 1초씩 감소시키는 역할을 합니다. 시험 시간이 0이 되면 endQuiz() 함수를 호출하여 시험을 종료합니다. cbtTime 요소에는 현재 시간을 표시합니다.
  2. 두 번째 함수인 displayTime은 시험 시간을 분:초 형식으로 표시하기 위한 함수입니다. 현재 시간이 0 이하인 경우 "0분 00초"를 반환하여 시험이 종료되었음을 표시합니다. 그 외의 경우에는 분과 초를 계산하여 "분 초" 형식으로 반환합니다. 초의 값이 한자리 수인 경우 "0초" 형식으로 반환될 수 있도록 조건문이 포함되어 있습니다.

 

 

이렇게 초의 값이 한 자릿수가 될 때 09초···01초처럼 두 자릿수가 되게 만들어주었습니다.

 

 


반응형
Adventure Time - BMO