Bomb Kirby Running

JAVASCRIPT

자바스크립트 퀴즈이펙트 07_02

^. ̫ .^ 2023. 4. 5. 21:50

728x90

 

어제에 이어 새로운 기능을 추가해보았습니다.

 

추가된 HTML

<div class="cbt__view">
    당신의 이름은 <input type="text" class="name">입니다.<br>
    당신은 <span class="subject">웹디자인 기능사 시험</span>을 선택했습니다.
</div>
<button class='cbt__start__btn'>시작하기</button>

 

 

추가된 script

선택자

const cbt = document.querySelectorAll(".cbt");
const cbtViewSubject = document.querySelector(".cbt__view .subject");
const cbtViewName = document.querySelector(".cbt__view .name");
const cbtHeader = document.querySelector(".cbt__header h2");
const cbtStart = document.querySelector(".cbt__start");
const cbtTime = document.querySelector(".cbt__time");
const cbtName = document.querySelector(".cbt__name");

let questionTime = "";  
let questionTimeRemain = "1000";
let quizScore = 0;

선택자로 각 요소들을 선택해주었습니다.

시작버튼

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

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

    // 이름 넣기
    const cbtViewNameValue = cbtViewName.value;
    cbtName.innerHTML = cbtViewNameValue;
}

"cbtStart"라는 HTML 요소에 "hide" 클래스를 추가하여 모달 창을 숨깁니다.

"questionTime" 변수에 1초마다 실행되는 "reduceTime" 함수를 인터벌로 설정하여 시간을 설정합니다.

"cbtViewName"이라는 HTML 요소에서 입력된 이름 값을 가져와 "cbtName"이라는 HTML 요소에 출력합니다.

 

없는 설명과 없는 이미지 제거

  //설명 없는거 제거
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");
   }
});

"cbt__question__desc" 클래스를 가진 요소들을 찾아서 내부 텍스트 값이 "undefined"인 경우 해당 요소에 "hide" 클래스를 추가합니다. 이를 통해, 설명이 없는 문제의 경우 해당 부분을 숨길 수 있습니다.

"cbt__question__img" 클래스를 가진 요소들을 찾아서 해당 요소 내부의 이미지 URL이 "undefined"를 포함하는 경우 해당 요소에 "hide" 클래스를 추가합니다. 이를 통해, 이미지가 없는 문제의 경우 해당 부분을 숨길 수 있습니다.

 

점수

const answerQuiz = () => {
	if(numberAnswer == question.answer){
        console.log("정답입니다.");
        cbtSelects[number].parentElement.classList.add("good");
        quizScore++;
    }
    document.querySelector(".score").innerHTML = `총 점수는 ${Math.ceil((quizScore / questionAll.length) * 100)}점입니다.`;
    cbtEnd.style.display = "block";
    clearInterval(questionTime);
}

answerQuiz 안에 추가해서 점수를 구했습니다 .

위에서 초기값을 0으로 설정했으므로 정답일때 마다 quizScore를 1씩 증가시켰습니다.

Math를 이용해 현재까지 맞춘 문제 수를 전체 문제 수로 나누어, 백분율로 변환한 값을 점수로 구해줍니다.

setInterval 함수는 일정한 시간 간격으로 지정한 함수를 반복적으로 실행하는 함수입니다.

 

모달창 없애기

 // 모달 창2 없애기
const cbtBtn2 = document.querySelector(".cbt__end__btn");
const cbtEnd = document.querySelector(".cbt__end");

cbtBtn2.addEventListener("click", () => {
    cbtEnd.style.display = "none"; 
});

없애지 않으면 문제를 선택해서 시작하기 전에 모달창이 한개가 더 뜹니다.

이걸 없애주기 위해 선택자로 선택하고 display = "none"을 설정해주었습니다.

문제 선택

 // 문제 선택
const changeSelect = (e) => {
    let selectValue = e.value;
    let selectText = e.options[e.selectedIndex].text;

    cbtViewSubject.innerText = selectText;
    cbtHeader.innerText = selectText;

    dataQuestion(selectValue);
}

selectValue 변수에 이벤트 객체의 value 값을 저장합니다.

selectText 변수에 이벤트 객체에서 선택된 옵션의 텍스트 값을 저장합니다.

cbtViewSubject 요소의 내부 텍스트 값을 selectText 값으로 변경합니다.

cbtHeader 요소의 내부 텍스트 값을 selectText 값으로 변경합니다.

dataQuestion 함수를 호출하며, 이때 인자로 selectValue 값을 전달합니다.

이 함수는 selectValue 값에 해당하는 문제 데이터를 가져와서 화면에 표시하는 역할을 수행합니다.

 

 

시간 설정

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

    if(questionTimeRemain == 0) endQuiz();

    cbtTime.innerText = displayTime();
}

questionTimeRemain 변수를 1씩 감소시킵니다.

만약 questionTimeRemain 값이 0이 되면 endQuiz() 함수를 호출합니다.

cbtTime 요소의 내부 텍스트를 displayTime() 함수의 반환값으로 변경합니다.

이 함수는 현재 시간을 "MM:SS" 형식으로 표시합니다.

시간 표시

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

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

questionTimeRemain 값이 0 이하인 경우 "0분 00초" 문자열을 반환합니다.

그렇지 않은 경우, 남은 시간을 분과 초로 나누어 계산합니다.

초 값이 한자리 수인 경우 앞에 "0"을 붙여주어 두 자리 수로 만듭니다.

반환값으로는 "분"과 "초" 문자열을 결합하여 "MM분 SS초" 형식으로 반환합니다.

시험 끝

// 시험 끝
const endQuiz = () => {
    alert("시험이 끝났습니다")
}

시험이 끝났을 때 알려주는 창이 나오도록 설정해줍니다.

 

마지막 부분

cbtStartBtn.addEventListener("click", startQuiz);
// dataQuestion();

버튼을 클릭했을때 startQuiz가 실행될 수 있도록 해주었습니다.