JAVASCRIPT

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

Kim do hyun 2023. 3. 25. 22:42
728x90
반응형

퀴즈 사이트 만들기 다섯번째

 

 

정보처리기능사 문제 풀이용으로 만들어본 퀴즈 사이트 다섯번째 입니다.

스크립트 코드만 정리하여 보여드리드록 하겠습니다.

 

 

 

JAVASCRIPT

// 문제 정보
const quizInfo = [
    {
        infoType: "정보처리 기능사",
        infoTime: "2007년 04월 01일(2회)",
        infoNumber: "20070201",
        infoQuestion: "flip-flop의 종류에 해당하지 않는 것은?",
        infoChoice: {
            1: "R-S",
            2: "J-K",
            3: "D",
            4: "R"
        },
        infoAnswer: "4",
        infoDesc: "R 플립플롭은 존재 하지 않습니다."
    },{
        infoType: "정보처리 기능사",
        infoTime: "2007년 04월 01일(2회)",
        infoNumber: "20070202",
        infoQuestion: "보기의 도형과 관련 있는 사항은?<br><img style='width:300px' src='../assets/img/noname01.tmp'>",
        infoChoice: {
            1: "OR 게이트",
            2: "버퍼(buffer)",
            3: "NAND 게이트",
            4: "인버터(Inverter)"
        },
        infoAnswer: "4",
        infoDesc: "그림은 인버터(NOT)입니다."
    },....
]
// 선택자
    const quizWrap = document.querySelector(".quiz__wrap");
    let quizScore = 0;

    // 문제 출력
    const updateQuize = () => {
        const exam = [];

        quizInfo.forEach((question, number) => {
            exam.push(`
                <div class="quiz">
                    <div class="quize__header">
                        <h2 class="quiz__title">${question.infoType} ${question.infoTime} </h2>
                    </div>
                    <div class="quize__main">
                        <div class="quiz__question"><em>${number+1}</em>. ${question.infoQuestion}</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__choice">
                            <label for="choice1${number}">
                                <input type="radio" id="choice1${number}" name="choice${number}" class="select" value="1">
                                <span>${question.infoChoice[1]}</span>
                            </label>
                            <label for="choice2${number}">
                                <input type="radio" id="choice2${number}" name="choice${number}" value="2">
                                <span>${question.infoChoice[2]}</span>
                            </label>
                            <label for="choice3${number}">
                                <input type="radio" id="choice3${number}" name="choice${number}" value="3">
                                <span>${question.infoChoice[3]}</span>
                            </label>
                            <label for="choice4${number}">
                                <input type="radio" id="choice4${number}" name="choice${number}" value="4">
                                <span>${question.infoChoice[4]}</span>
                            </label>
                        </div>
                        <div class="quiz__desc">정답은 <em>${question.infoAnswer}</em> 번 입니다.<br>${question.infoDesc}</div>
                    </div>
                </div>
            `)
        });
        exam.push(`
            <div class="quiz__info">??점</div>
            <div class="quiz__check">정답 확인</div> 
        `);

        quizWrap.innerHTML = exam.join("");

    // 설명 숨기기
    document.querySelectorAll(".quiz__desc").forEach(el => el.style.display = "none");

    }
    updateQuize();

    // 정답 확인
    const answerQuiz = () => {
        const quizChoices = document.querySelectorAll(".quiz__choice")

        //사용자가 체크한 정답 == 문제 정답
        quizInfo.forEach((question, number)=>{
            const userSelector = `input[name=choice${number}]:checked`;
            const quizSelectorWrap = quizChoices[number];
            const userAnswer = (quizSelectorWrap.querySelector(userSelector)|| {}).value;
            const dogWrap = quizWrap.querySelectorAll(".dog__wrap");

            if(userAnswer == question.infoAnswer){
                dogWrap[number].classList.add("like");
                quizScore++;
            } else {

                dogWrap[number].classList.add("dislike");
            }
        });
        // 설명 보이기
        document.querySelectorAll(".quiz__desc").forEach(el => el.style.display = "block");

        // 점수 보이기
        document.querySelector(".quiz__info").innerHTML = Math.ceil((quizScore / quizInfo.length)* 100) +"점";
    }



    // 정답 클릭
    document.querySelector(".quiz__check").addEventListener("click", answerQuiz);


</script>

 

코드 설명

// 문제 정보

배열 안에 객체를 저장하는 방법을 이용하여 quizInfo 안에 문제에 대한 정보 데이터를 저장합니다.

 

// 선택자

HTML 문서 내에서 클래스 이름이 "quiz__wrap"인 요소를 선택하고, 해당 요소를 JavaScript 코드에서 사용할 수 있도록 변수로 참조할 수 있게 됩니다. 이 변수를 사용하여 해당 요소의 속성, 스타일 등을 변경하거나 이벤트를 추가하는 등의 동작을 수행할 수 있습니다.

 

// 문제 출력

위 코드에서 ${question.infoType} ${question.infoTime}은 템플릿 리터럴(template literal)을 사용하여 문자열을 동적으로 생성하는 부분입니다.

여기서 question은 quizInfo 배열의 각 요소들 중 하나를 의미하며, infoType과 infoTime은 그 요소 안에 있는 프로퍼티들입니다.

따라서 ${question.infoType} ${question.infoTime}은 각 question 요소의 infoType과 infoTime 프로퍼티 값을 문자열로 조합하여 출력하는 것입니다.

예를 들어, quizInfo 배열 안에 있는 첫 번째 요소의 infoType 값이 "Multiple Choice"이고 infoTime 값이 "30 minutes"이라면 ${question.infoType} ${question.infoTime}은 "Multiple Choice 30 minutes" 문자열을 출력하게 됩니다.

 

 

// 설명 보이기

위 코드는 querySelectorAll() 메소드를 사용하여 HTML 문서에서 클래스 이름이 "quiz__desc"인 모든 요소들을 선택하고, 선택된 모든 요소들에 대해 forEach() 메소드를 호출하여 각각의 요소에 대해 style.display 속성 값을 "block"으로 설정하는 것입니다.

이 속성 값이 "block"으로 설정되면 해당 요소들이 브라우저에 표시됩니다. 따라서 이 코드는 선택된 모든 요소들을 화면에 보이게 만드는 역할을 합니다.

 

 

// 정답 클릭

위 코드는 querySelector() 메소드를 사용하여 HTML 문서에서 클래스 이름이 "quiz__check"인 요소를 선택하고, 선택된 요소에 대해 addEventListener() 메소드를 호출하여 "click" 이벤트에 대한 이벤트 핸들러 함수인 answerQuiz를 등록하는 것입니다.

따라서 이 코드는 사용자가 "quiz__check" 클래스를 가진 요소를 클릭할 때, answerQuiz 함수가 호출되도록 하는 역할을 합니다.

addEventListener() 메소드는 이벤트를 등록하는 메소드로, 첫 번째 인자로 등록하려는 이벤트 종류를 문자열로 전달하고, 두 번째 인자로 이벤트가 발생했을 때 실행될 콜백 함수를 전달합니다.

여기서 "click" 이벤트는 사용자가 요소를 클릭했을 때 발생하는 이벤트이며, answerQuiz 함수는 이 이벤트가 발생했을 때 실행됩니다.

 

push(), join()

push(): 배열의 끝에 하나 이상의 요소를 추가하는 메소드입니다. 새로운 요소를 배열의 끝에 추가하고, 배열의 길이(length)를 반환합니다.
join(): 배열의 모든 요소를 하나의 문자열로 연결하는 메소드입니다. 연결할 때 요소들 사이에 특정 구분자(separator)를 지정할 수 있으며, 지정하지 않으면 기본값인 쉼표(,)를 사용합니다.