본문 바로가기
JAVASCRIPT

퀴즈 이펙트 : 객관식 확인하기 : CBT 유형(json) 보충2

by dongjin6539 2023. 4. 5.
728x90
반응형

퀴즈 이펙트 : 객관식 확인하기 : CBT 유형(json) 보충2

https://dongjin6539.tistory.com/64, https://dongjin6539.tistory.com/65 블로그 보충

코드 보기(HTML, JAVASCRIPT / CSS1 / CSS2 / JSON) / 완성화면

 

 

코드 추가 구성

 <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="cbt__start__btn">시작하기</button>
    </div>
</div>
<div class="cbt__end">
    <div class="cbt__modal2">
        <h2>수고하셨습니다.</h2>
        <div class="score"></div>
        <button class="cbt__end__btn">문제 확인하기</button>
    </div>
</div>

 

구성

  • 시작 모달 창을 만들어줍니다.
  • 모달 창에 문제 유형을 선택하는 것을 만들어줍니다.
  • 시험을 시작하는 버튼을 만들어줍니다.
  • 끝 모달 창을 만들어줍니다.
  • 모달 창 안에 점수가 나오게 해줍니다.
  • 틀린문제를 확인하기 위해 다시 문제를 확인 할 수 있는 버튼을 만들어줍니다.
  • 문제 유형을 선택하는 부분에 문제 유형을 선택하면 문제가 변경 될 수 있게 onchange="changeSelect(this)"를 입력해줍니다.

 

JAVASCRIPT

<script>
    // 선택자
    const cbtScore = document.querySelector(".cbt__score");	// 점수 위치 선택자
    const cbtViewSubject = document.querySelector(".cbt__view .subject");	// 문제 유형 선택부분 선택자
    const cbtHeader = document.querySelector(".cbt__header span");	// 문제 유형 나오는 위치 선택자
    const cbtStartBtn = document.querySelector(".cbt__start__btn");	// 시작하기 버튼 선택자
    const cbtStart = document.querySelector(".cbt__start");	// 모달 창 선택자
    
    let quizScore = 0;	// 점수
    let questionTime = "";	// 시간
    let questionTimeRemain = "3600";  // 시간 숫자
    
    // 시작하기
    const startQuiz = () => {
        cbtStart.classList.add("hide"); // 모달창 제거

        // 시간 설정
        questionTime = setInterval(reduceTime, 1000);
        
        // input 사용자 이름 입력하는 값 불러오기
        const cbtName = document.querySelector(".cbt__name");
        const myInfo = document.querySelector(".cbt__view .name");
        const myInfoValue = myInfo.value;

        cbtName.innerHTML = myInfoValue;
    };
    
    // 데이터 불러오기
    const dataQuestion = (value) => {
        fetch(`https://kebab000.github.io/web2023/gineungsaJSON/${value}.json`)
    }
    
    // 정답 확인
    const answerQuiz = () => {
        document.querySelector(".score").innerHTML = `총 점수는 ${Math.ceil((quizScore / questionAll.length) * 100)}점입니다.`;

        cbtEnd.style.display = "block";

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

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

        dataQuestion(selectValue);
    };

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

        if(questionTimeRemain == 0) endQuiz();

        cbtTime.innerText = displayTime();
    }

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

            // 초의 단위가 한자리 수가 되면 앞에 0을 붙여주기
            return `${minutes}분 ${seconds.toString().padStart(2, '0')}초`;
        }
    };
    
    // 시험 끝
    const endQuiz = () => {
        alert("시험이 끝났습니다.");
    }; 
    
    // 모달 창2 없애기
    const cbtBtn2 = document.querySelector(".cbt__end__btn");
    const cbtEnd = document.querySelector(".cbt__end");

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

    cbtStartBtn.addEventListener("click", startQuiz);
    cbtSubmit.addEventListener("click", answerQuiz);
</script>

 

자바스크립트 구성

문제 유형 선택창에서 JSON 파일 데이터 불러오기
  • 코드 블럭에 onchange = changeSelect(this)를 이용해서 변수 changeSelect를 만들어줍니다.
  • 그 부분에 값을 가져와서 변수로 만들어줍니다.
  • 코드 블럭에 option 태그를 사용했으므로 "값.option[값.selectIndex].텍스트"를 변수로 만들어줍니다.
  • 데이터를 불러오는 변수에 매개변수로 부분의 값을 변수로 만든 것을 매개변수 값을 입력해줍니다.
  • 매개변수를 입력했으므로 데이터를 불러오는 쪽에 가져올 수 있도록 매개변수를 입력해줍니다. 

 

타이머 만들기
  • // 시간 설정, // 시간 표시 부분을 확인해보시면 됩니다.
  • 변수를 설정해줍니다. 그리고 변수를 설정해서 함수를 사용해서 실행시켜줍니다.
  • questionTimeRemain 변수에 저장된 숫자를 --연산자를 사용해서 감소하게 해줍니다.
  • if문을 사용해서 숫자가 0이 되면 만들어둔 끝나는 함수 endQuiz를 실행시켜줍니다.
  • 시간 표시를 해주는데 함수를 사용해서 실행시켜줍니다.
  • if문을 사용해서 questionTimeRemain이 0이하이면 return을 사용해서 0분 0초를 반환시키게 해줍니다.
  • if문 조건문에 해당하지 않으면 minutes 변수에  questionTimeRemain 변수에 저장된 숫자를 60으로 나눈 값이 나오게 해주고 seconds 변수에 questionTimeRemain 변수에 저장된 숫자를 60으로 나눈 나머지 값이 나오게 해줍니다. 그리고 return을 사용해서 `${minutes}분 ${seconds.toString().padStart(2, '0')}초`인지 반환시켜 줍니다.
  • 그리고 사용자가 시작하기 버튼을 누르면 흘러가게 하기 위해서 // 시작하기 부분에 시간 변수 = setInterval(시간 설정 변수, 1000)을 사용해서 흘러가게 해줍니다.
  • 마지막으로 답안 제출하면 먼추게 하기 위해서 // 정답 확인을 눌렀을 때 clearInterval(시간변수)를 사용해서 멈춰줍니다.
초 단위가 한 자리 수가 되면 앞에 0 붙이기
  • 초 단위를 문자열로 가져오게 하기 위해 .toString( )를 사용해주고 .padStart( ) 메서드를 사용해주는데 padStart( ) 메서드는 문자열의 왼쪽에 지정한 길이만큼 다른 문자열을 삽입하여 길이를 맞추어 줍니다. 
  • 그래서 문자열의 길이를 2로 만들고, 왼쪽에 '0' 을 삽입하게 해줍니다.
Input 창에 사용자 이름 입력 값 불러오기
  • 시작하기 버튼을 클릭하면 입력 값을 옮기기 위해서 // 시작하기 함수 부분에 입력을 해줍니다.
  • 입력될 부분을 선택자를 만들고, input 부분을 선택자로 만들고, 사용자가 입력한 input 부분의 값을 변수로 저장해줍니다.
  • 저장해준 데이터를 확인 후 "입력될 부분 선택자.innerHTML = 사용자가 입력한 input 부분의 값의 변수"를 입력시켜줍니다.
점수 결과 표시
  • 모달 창을 하나 더 만들어줍니다.
  • 하나 더 만들어서 각각 선택자를 만들어 줍니다.
  • 결과 창이므로 처음엔 숨겨주고 정답 확인하면 나오게 style.display="block"을 해줍니다.
  • 점수가 나오게 하기 위해 변수 score을 만들고 0 데이터를 저장해줍니다.
  • 변수 score을 정답이면 score++; 연산자를 사용해서 출력해줍니다.
  • 정답 확인 후 점수가 뜨게 하기 위해 모달 창 안에 태그를 만들어서 .innerHTML 을 입력해서 총 문제의 갯수에 점수를 나눠주고 *100을 해서 Math.ceil 메서드를 사용해 소수점을 올림해줘서 점수가 나오게 해줍니다.

 

참고

속성, 메서드 설명
toString( ) 문자열을 반환합니다.
padStart( ) 현재 문자열의 시작을 다른 문자열로 채워, 주어진 길이를 만족하는 새로운 문자열을 반환합니다. 채워넣기는 대상 문자열의 시작(좌측)부터 적용됩니다.
setInterval
호출 사이에 고정된 시간이 지연되면 이를 반복적으로 호출을 실행합니다.
clearInterval
호출로 이전에 설정된 시간 제한 반복 작업을 취소합니다.
Math.floor( ) 항상 내림하고 주어진 숫자보다 작거나 같은 가장 큰 정수를 반환합니다.

 

728x90
반응형