728x90
반응형

 

완성 화면

 

 

 

 

 

 

코드 보기 / HTML

 <main id="main">
        <div class="quiz__wrap__cbt">
            <div class="cbt__header">
                <h2>2020년 1회 정보처리기능사 기출 문제 </h2>
            </div>
            <div class="cbt__content">
                <div class="cbt__quiz">
                    <!-- <div class="cbt">
                        <div class="cbt__question"><span>1. </span>객체지향 프로그램에서 데이터를 추상화하는 단위는?</div>
                        <div class="cbt__question__img"><img src="img/gineungsaJC2020-02.jpg" alt=""></div>
                        <div class="cbt__selects">
                        <div>
                                <input type="radio" id="select1">
                                <label for="select1"><span>클래스</span></label>
                                <input type="radio" id="select2">
                                <label for="select2"><span>메서드</span></label>
                                <input type="radio" id="select3">
                                <label for="select3"><span>상속</span></label>
                                <input type="radio" id="select4">
                                <label for="select4"><span>메시지</span></label>
                        </div>
                        <div class="cbt__desc">객체지향프로그램</div>
                        <div class="cbt__keyword">추상화 어쩌구</div>
                    </div> -->
                    <div class="cbt">
                        <div class="cbt__question"><span>1. </span>객체지향 프로그램에서 데이터를 추상화하는 단위는?</div>
                        <div class="cbt__question__desc">객체 지향 언어는  ___________ 이다.</div>
                        <div class="cbt__selects">
                            <div>
                                <input type="radio" id="select1">
                                <label for="select1"><span>클래스</span></label>
                                <input type="radio" id="select2">
                                <label for="select2"><span>메서드</span></label>
                                <input type="radio" id="select3">
                                <label for="select3"><span>상속</span></label>
                                <input type="radio" id="select4">
                                <label for="select4"><span>메시지</span></label>
                            </div>
                        </div>
                        <div class="cbt__desc">객체지향프로그램</div>
                        <div class="cbt__keyword">추상화 어쩌구</div>
                    </div>
                </div>
            </div>
            <div class="cbt__aside">
                <div class="cbt__info">
                    <div>
                        <span class="cbt__time">남은 시간 :<em></em></span>
                        <button class="cbt__submit">답안지 제출</button>
                    </div>
                    <div>
                        <div class="cbt__title">수험자 : <em class="cbt__name"></em></div>
                        <div class="cbt__score">
                            <span> 전체 문항 수 : <em class="cbt__length"></em>문항</span> <br>
                            <span> 잔여 문항 수 : <em class="cbt__count"></em>문항</span> <br>
                        </div>
                    </div>
                </div>
                    <div class="cbt__omr">
                        <!-- <div class="omr">
                            <strong>1</strong>
                            <input type="radio" id="omr0_1">
                            <label for="omr0_1">
                                <span class="label-inner">1</span>
                            </label>
                            <input type="radio" id="omr0_2">
                            <label for="omr0_2">
                                <span class="label-inner">2</span>
                            </label>
                            <input type="radio" id="omr0_3">
                            <label for="omr0_3">
                                <span class="label-inner">3</span>
                            </label>
                            <input type="radio" id="omr0_4">
                            <label for="omr0_4">
                                <span class="label-inner">4</span>
                            </label>
                        </div> -->
                    </div>
            </div>
        </div>
        <div class="cbt__start">
            <div class="cbt__modal__start">
                <h2>종목 선택</h2>
                <div class="cbt__items">
                    <select name="cbtTime" id="cbtTime" class="items1" 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_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" class="items2" 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>
                <div data-lit-hue="20" data-lit-count="100" class="lit-container">
                    <button id="startbtn" class="minimal">시험 시작</button>
                </div>
            </div>
        </div>
        <div class="cbt__end">
            <div class="cbt__modal__end">
                <h2>🎊 수고하셨습니다.</h2>
                <div class="cbt__endscore"></div>
                <button class="return">시험지로 돌아가기 </button>
            </div>
        </div>
        
    </main>

 

 

 

코드 보기 / JAVASCRIPT

const cbtHeader = document.querySelector(".cbt__header h2");
        const cbtStart = document.querySelector(".cbt__start");
        const cbtEnd = document.querySelector(".cbt__end");
        const cbtStartBtn = document.querySelector(".cbt__start .minimal");
        const cbtEndBtn = document.querySelector(".cbt__end .return");
        const cbtTime = document.querySelector(".cbt__time em");
        const cbtEndscore = document.querySelector(".cbt__endscore");

        let questionAll = [];                          //모든 문제 정보
        let quizLength = 0;                     //전체 문항 수
        let questioncount = quizLength;         //남은 문항 수

        //시험 결과 관련 변수
        let truescore = 0;                  //맞은 갯수
        let falsescore = 0;                 //틀린 갯수

        //제한시간 변수
        let TimeLimit = "";
        let RemainTime = "3600";

        cbtEnd.classList.add("hide");
        //시험 시작
        const startQuiz = () => {
            cbtStart.classList.add("hide");          //modal 제거

            const inputEl = document.querySelector('.name');            // input에서 입력받은 요소 선택
            const userName = document.querySelector(".cbt__title em");  // em 요소 선택
            const inputValue = inputEl.value;                           //input에서 입력된 값 가져오기

            userName.textContent = inputValue;                          // em 요소에 입력된 값 넣기

            //제한시간
            TimeLimit = setInterval(reduceTime, 3600);
        }
        
        
        -----------<정답 확인 시>-------
        const cbtSelects = document.querySelectorAll(".cbt__selects");
                let Score = 0;

                questionAll.forEach((question, number) => {
                    const quizSelectsWrap = cbtSelects[number];
                    const userSelector = `input[name=select${number}]:checked`;
                    const userAnswer = (quizSelectsWrap.querySelector(userSelector) || {}).value;
                    const numberAnswer = userAnswer ? userAnswer.slice(-1) : undefined;


                    if(numberAnswer == question.answer) {
                        console.log("정답")
                        truescore++;
                        cbtSelects[number].parentElement.classList.add("good");
                    } else {
                        console.log("오답")
                        falsescore++;
                        cbtSelects[number].parentElement.classList.add("bad");

                        //오답일 경우 정답 표시
                        const label = cbtSelects[number].querySelectorAll("label");
                        label[question.answer-1].classList.add("correct");
                    }
                    
                    //설명 숨기기
                    const quizDesc = document.querySelectorAll(".cbt__desc");
                    
                    if(quizDesc[number].innerText == "undefined"){
                        quizDesc[number].classList.add("hide");
                    } else {
                        quizDesc[number].classList.remove("hide");
                    }
                    
                });
                Score = Math.round((Score/questionAll.length)*100);
                cbtEnd.classList.remove("hide");
                cbtEndscore.innerHTML = "총"+truescore+"문항을 맞추셨습니다.<br> 틀린 문항 수는 "+falsescore+"개 이며, 총점은 "+Score+"입니다.";

            }
            
            ------------<제한시간>------------------
            //제한시간 설정
        const reduceTime = () => {
            RemainTime--;

            if(RemainTime == 0) endQuiz();

            cbtTime.innerText = displayTime();
        }

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

                //초의 단위가 한자리 수가 되면 앞에 0을 붙여주기
                if(minutes.toString().length == 1){
                    minutes = "0"+minutes;
                }

                if(seconds.toString().length == 1){
                    seconds = "0"+seconds;
                }

                return minutes + "분" + seconds + "초";
            }
        }
        
        
      -----------------<종목 선택>---------------
      //종목 선택
        const changeSelect = (ev) => {
            let selectValue = ev.value;
            let selectText = ev.options[ev.selectedIndex].text;

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

            dataQuestion(selectValue);
        }

 

 

 

 

 

제한 시간

 ----------<제한시간 변수>-----------
        let TimeLimit = "";
        let RemainTime = "3600";
        
        
        TimeLimit = setInterval(reduceTime, 3600);
        
        
        -------<제한시간 설정>-----------
           const reduceTime = () => {
            RemainTime--;

            if(RemainTime == 0) endQuiz();

            cbtTime.innerText = displayTime();
        }
        
        -----<제한 시간을 화면에 표시>---------
         const displayTime = () => {
            if(RemainTime <= 0){
                return "0분 00초";
            } else {
                let minutes = Math.floor(RemainTime / 60);
                let seconds = RemainTime % 60;

                //초의 단위가 한자리 수가 되면 앞에 0을 붙여주기
                if(minutes.toString().length == 1){
                    minutes = "0"+minutes;
                }

                if(seconds.toString().length == 1){
                    seconds = "0"+seconds;
                }

                return minutes + "분" + seconds + "초";
            }
        }

 

TimeLimit 변수의 초기값은 빈 문자열이며, RemainTime 변수의 초기값은 3600으로 설정된다.

이는 1시간에 해당하는 초수를 나타낸다.

setInterval 함수를 사용하여 reduceTime 함수를 3600밀리초(즉, 1시간)마다 호출하도록 설정된다.

reduceTime 함수는 남은 시간(RemainTime)을 1초씩 줄이고, 남은 시간이 0이 되면 endQuiz 함수를 호출한다.

또한 cbtTime 요소의 텍스트를 displayTime 함수가 반환하는 포맷된 문자열로 업데이트한다.

displayTime 함수는 남은 시간(RemainTime)을 입력으로 받아 카운트다운의 남은 분과 초를 계산하여, "mm분 ss초" 형식으로 남은 시간을 나타내는 포맷된 문자열을 반환한다.

여기서 "mm"은 분을, "ss"는 초를 나타냅니다. 남은 시간이 0보다 작거나 같으면 함수는 "0분 00초"를 반환한다.

reduceTime 함수에서 displayTime 함수를 호출하여 cbtTime 요소의 텍스트를 업데이트한다.

 

 

 

 

종목 선택

const changeSelect = (ev) => {
            let selectValue = ev.value;
            let selectText = ev.options[ev.selectedIndex].text;

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

            dataQuestion(selectValue);
        }

 

changeSelect 함수를 정의하는 것으로, 이 함수는 select 요소에서 옵션을 선택하면 호출된다.

ev는 이벤트 객체를 나타내며, 선택된 옵션의 값을 가져와 selectValue 변수에 할당하며, 선택된 옵션의 텍스트를 가져와 selectText 변수에 할당한다.
cbtViewSubject 요소의 텍스트와 cbtHeader 요소의 텍스트를 선택된 옵션의 텍스트로 변경한다.
마지막으로, dataQuestion 함수를 호출하여 선택된 옵션의 값을 인수로 전달한다.

이 함수는 이 값을 기반으로 데이터를 가져와 해당 데이터를 사용하여 문제를 표시하는 작업을 수행한다.

 

 

 

 

 

정답 확인 버튼 클릭 시, 점수와 틀린 문항과 맞은 문항 표시

 const answerQuiz = () => {
                const cbtSelects = document.querySelectorAll(".cbt__selects");
                let Score = 0;

                questionAll.forEach((question, number) => {
                    const quizSelectsWrap = cbtSelects[number];
                    const userSelector = `input[name=select${number}]:checked`;
                    const userAnswer = (quizSelectsWrap.querySelector(userSelector) || {}).value;
                    const numberAnswer = userAnswer ? userAnswer.slice(-1) : undefined;


                    if(numberAnswer == question.answer) {
                        console.log("정답")
                        truescore++;
                        cbtSelects[number].parentElement.classList.add("good");
                    } else {
                        console.log("오답")
                        falsescore++;
                        cbtSelects[number].parentElement.classList.add("bad");

                        //오답일 경우 정답 표시
                        const label = cbtSelects[number].querySelectorAll("label");
                        label[question.answer-1].classList.add("correct");
                    }
                    
                    //설명 숨기기
                    const quizDesc = document.querySelectorAll(".cbt__desc");
                    
                    if(quizDesc[number].innerText == "undefined"){
                        quizDesc[number].classList.add("hide");
                    } else {
                        quizDesc[number].classList.remove("hide");
                    }
                    
                });
                FinalScore = Math.round((truescore/questionAll.length)*100);
                cbtEnd.classList.remove("hide");
                cbtEndscore.innerHTML = "총"+truescore+"문항을 맞추셨습니다.<br> 틀린 문항 수는 "+falsescore+"개 이며, 총점은 "+FinalScore+"입니다.";

            }

 

 

시험이 종료된 후 사용자의 답을 검사하고, 사용자가 맞춘 문제 수와 틀린 문제 수, 총점을 계산하여 화면에 출력하는 역할을 한다.


함수 내부에서는 우선 document.querySelectorAll(".cbt__selects")를 사용하여 HTML 문서 내의 모든 문제 선택지를 가져온다.

그 후,  questionAll 배열에 저장된 모든 문제에 대해 반복문을 실행하면서, 각 문제의 정답과 사용자의 선택지를 비교하고, 맞은 문제와 틀린 문제의 수를 카운트한다.

 

이 때, 맞은 문제일 경우 cbtSelects[number].parentElement.classList.add("good")를 사용하여 동그라미 표를 나타내고, truescore 변수를 1씩 증가시키며,  틀린 문제일 경우 cbtSelects[number].parentElement.classList.add("bad")를 사용하여 틀렸다는 표시인 붉은 사선을 나타내고, 맞는 선택지를 빨간색으로 바꾸어 정답을 표시하고 falsescore 변수를 1씩 증가시킨다.

또한, 각 문제에 대해 quizDesc를 사용하여 문제에 대한 설명을 가져와, 이 설명이 있는 경우에는 이를 화면에 보여주고, 없는 경우에는 숨긴다.

 

truescore 변수는 카운트 된 정답 수이며, falsescore 변수는 카운트 된 오답 수이다.

이 두 변수를 사용하여, 맞춘 문항 수와 틀린 문항 수를 화면에 출력한다.

FinalScore 변수는 총점을 계산한다.

총점은 맞춘 문항 수(truescore)를 전체 문항 수(questionAll)로 나눈 후, 100을 곱한 값입니다. Math.round() 함수를 사용하여 소수점 이하를 반올림하고, cbtEndscore.innerHTML을 사용하여 최종 결과를 화면에 출력한다.

 

 

 

 

 

 

시험 시작 버튼 클릭 시, OMR 답지 위에 입력 된 수험자의 이름을 표시

const startQuiz = () => {
            cbtStart.classList.add("hide");          //modal 제거

            const inputEl = document.querySelector('.name');            // input에서 입력받은 요소 선택
            const userName = document.querySelector(".cbt__title em");  // em 요소 선택
            const inputValue = inputEl.value;                           //input에서 입력된 값 가져오기

            userName.textContent = inputValue;                          // em 요소에 입력된 값 넣기

            //제한시간
            TimeLimit = setInterval(reduceTime, 3600);
        }

 

 

사용자가 입력한 이름을 가져와서 해당 이름을 모달 창의 제목에 넣는 역할을 하는 코드이다.

먼저 document.querySelector('.name')을 사용하여 HTML에서 name 클래스를 가진 요소를 찾는다.

그리고 inputValue 변수에 해당 요소의 값(value)을 할당한다.

그 후, document.querySelector(".cbt__title em")를 사용하여 HTML에서 cbt__title 클래스를 가진 요소의 자식 요소인 em 요소를 찾아 textContent를 사용하여 inputValue를 할당하여 OMR 답안지 위에 수험자의 이름을 표시한다.

 

 

 

 

 

 

 

 

 

 

 

 

 

+ Recent posts