예제/퀴즈 이펙트

퀴즈 이펙트_주관식 문제를 만들어 봅시다!

아라라_ 2023. 3. 9. 20:50

“ 지연되는 프로젝트에 인력을 더 투입하면 오히려 더 늦어진다. ”

Frederick Philips Brooks
Mythical Man-Month 저자
728x90

오늘은 주관식 정답 판별하는 문제를 만들어 보았습니다.

오늘은 사용자가 답을 직접 적고 정답의 유무를 판별 하는 페이지를 만들어 보겠습니다.

html의 구조와 css는 어제 와 비슷해서 올리지는 않았습니다.

오늘은 자바스크립트 위주로 설명드릴려고합니다. 

현재 페이지는 사용자가 답을 적으면 답을 적는 박스와 버튼이 사라지면서 답과 팁이 나오고 강아지의 표정이 바뀌는 페이지입니다.

 

<!DOCTYPE html>
<html lang="ko">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>퀴즈 이펙트02</title>

    <link rel="stylesheet" href="css/reset.css">
    <link rel="stylesheet" href="css/quiz.css">
</head>
<body >
    <header id="header">
        <h1><a href="../javascript14.html">Quiz </a><em>주관식 확인하기 유형</em></h1>
        <ul>
            <li><a href="quizEffect01.html">1</a></li>
            <li class="active"><a href="quizEffect02.html">2</a></li>
        </ul>
    </header>
    <!-- // header -->

    <main id="main">
        <div class="quiz__wrap">
            <div class="quiz">
                <div class="quiz__header">
                    <h2 class="quiz__title"><span></span> <em></em></h2>
                </div>
                <div class="quiz__main">
                    <div class="quiz__question">
                        <em></em>. <span></span>
                    </div>
                    <div class="quiz__view">
                        <div class="dog__wrap">
                            <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>
                <div class="quiz__answer">
                    <input class="input" type="text" placeholder="멍! 정답을 적어주세요!">
                    <button class="confirm">정답 확인하기</button>
                    <div class="result"></div>
                </div>
                <div class="quiz__footer">
                    <div class="quiz__desc"></div>
                </div>
            </div>
        </div>
    </main>
    <!-- // main -->

    <footer id="footer">
        <a href="mailto:jo0132@naver.com">jo0132@naver.com</a>
    </footer>
    <!-- // footer -->

    <script>
        // 선택자
        const quizWrap = document .querySelector(".quiz__wrap")
        const quizTitle = quizWrap .querySelector(".quiz__title span")
        const quizTime = quizWrap .querySelector(".quiz__title em")
        const quizQuestionNum = quizWrap.querySelector(".quiz__question em")
        const quizQuestion = quizWrap.querySelector(".quiz__question span")
        const quizDesc = quizWrap.querySelector(".quiz__desc")
        const quizAnswerConfirm = quizWrap.querySelector(".quiz__answer .confirm")
        const quizAnswerResult = quizWrap.querySelector(".quiz__answer .result")
        const quizAnswerInput = quizWrap.querySelector(".quiz__answer .input")
        const quizFooter = quizWrap.querySelector(".quiz__footer")
        const dogwrap = quizWrap.querySelector(".dog__wrap")


        // 문제 정보
        const infoType = "정보처리 기능사";
        const infoTime = "2011년 5회";
        const infoNumber = "2"
        const infoQuestion = " 프레젠테이션에서 화면 전체를 전환하는 단위를 의미하는 것은?";
        const infoAnswer =  "슬라이드";
        const infoDesc = "슬라이드는 프리젠테이션의 화면 전체를 말하고 개체는 화면을 구성하고 개개의 요소를 말한다.";


        // 문제 출력
        quizTitle.textContent = infoType;
        quizTime.textContent = infoTime;
        quizQuestionNum.textContent = infoNumber;
        quizQuestion.textContent = infoQuestion;
        quizDesc.textContent = infoDesc;
        quizAnswerResult.textContent = infoAnswer;

        // 정답 숨기기
        quizAnswerResult.style.display = "none";
        quizFooter.style.display = "none";

        // 사용자 정답
        quizAnswerConfirm.addEventListener("click",function(){
            const userAnswer = quizAnswerInput.value.trim();    //userAnswer를 만들어 quizAnswerInput에서 받은 답을 띄여쓰기 상관없이 오로지 답만 볼 수있게 만들어 줍니다.

            quizAnswerConfirm.style.display = "none";   // 정답 학인 버튼 숨김
            quizAnswerInput.style.display = "none";     // 인풋 박스 숨김
            quizAnswerResult.style.display = "block";   // 정답 보기
            quizFooter.style.display = "block";         // 해설 보기

            if (infoAnswer == userAnswer){
                // alert("정답입니다.")
                dogwrap.classList.add("like");
                dogwrap.classList.remove("dislike");
            } else {
                // alert("오답입니다.")
                dogwrap.classList.add("dislike");
                dogwrap.classList.remove("like");

            }
        });
        





    </script>
</body>
</html>

이렇게 코딩합니다.

그중 javascript를 따로 이야기해보겠습니다.

 

const quizWrap = document .querySelector(".quiz__wrap")
const quizTitle = quizWrap .querySelector(".quiz__title span")
const quizTime = quizWrap .querySelector(".quiz__title em")
const quizQuestionNum = quizWrap.querySelector(".quiz__question em")
const quizQuestion = quizWrap.querySelector(".quiz__question span")
const quizDesc = quizWrap.querySelector(".quiz__desc")
const quizAnswerConfirm = quizWrap.querySelector(".quiz__answer .confirm")
const quizAnswerResult = quizWrap.querySelector(".quiz__answer .result")
const quizAnswerInput = quizWrap.querySelector(".quiz__answer .input")
const quizFooter = quizWrap.querySelector(".quiz__footer")
const dogwrap = quizWrap.querySelector(".dog__wrap")

 

선택자들에 쿼리 선택자를 사용하여 각각의 변수에 저장합니다. 이때 DOM에서 HTML 요소를 천택하고 변순에 할당하엿습니다.

첫번째만 클래스가 quiz__wrap인 HTML요소를 선택하고 선택한 요소를 quizWrap에 할당하였습니다.

그 다음 선택자부터는 변수에서  클래스를 찾아 선택하고 변수에 할당합니다.

그 이유는 변수를 사용하여 선택된 html요소에 쉽게 접근하고 조작할 수 있습니다. 이를 통해 javascript코드에서 html이나 css스타일 등을 조작하거나 변경할 수 있습니다.

 

const infoType = "정보처리 기능사";
const infoTime = "2011년 5회";
const infoNumber = "2"
const infoQuestion = " 프레젠테이션에서 화면 전체를 전환하는 단위를 의미하는 것은?";
const infoAnswer =  "슬라이드";
const infoDesc = "슬라이드는 프리젠테이션의 화면 전체를 말하고 개체는 화면을 구성하고 개개의 요소를 말한다.";

 

그 후 출력하고자 하는 정보들을 변수에 저장하여 javascript에서 쉽게 사용할 수 있도록 준비합니다.

 

quizTitle.textContent = infoType;
quizTime.textContent = infoTime;
quizQuestionNum.textContent = infoNumber;
quizQuestion.textContent = infoQuestion;
quizDesc.textContent = infoDesc;
quizAnswerResult.textContent = infoAnswer;

 

그 다음으로 먼저 저장한 선택자 변수에 textContent를 사용하여 각각의 선택자안에 필요한 text를 넣은 코드를 적습니다.

이때 textContent는 요소(element)의 텍스트 콘텐츠(text content)를 가져오거나 설정하는 속성(property)입니다.

이렇게 되면 출력이 완료가 되었습니다.

 

quizAnswerResult.style.display = "none";
quizFooter.style.display = "none";

 

하지만 문제를 푸는데 정답이 나올수 없으니 가려주어야하는데 이때 사용하는 것이 [선택자변수.style.display]입니다 

이 코드를 사용하면 해당 선택자변수가 가지고 있는 선택자에게 스타일을 부여할 수있습니다.

 

quizAnswerConfirm.addEventListener("click",function(){
    const userAnswer = quizAnswerInput.value.trim();    //userAnswer를 만들어 quizAnswerInput에서 받은 답을 띄여쓰기 상관없이 오로지 답만 볼 수있게 만들어 줍니다.

    quizAnswerConfirm.style.display = "none";   // 정답 학인 버튼 숨김
    quizAnswerInput.style.display = "none";     // 인풋 박스 숨김
    quizAnswerResult.style.display = "block";   // 정답 보기
    quizFooter.style.display = "block";         // 해설 보기

    if (infoAnswer == userAnswer){
        // alert("정답입니다.")
        dogwrap.classList.add("like");
        dogwrap.classList.remove("dislike");
    } else {
        // alert("오답입니다.")
        dogwrap.classList.add("dislike");
        dogwrap.classList.remove("like");
    }
});

 

다음은 사용자 정답을 판별하는 것입니다.

 

버튼의 선택자 태그에 addEnentListener()이라는 이벤트를 처리해주는 함수에 클릭하면 함수 가 실행되도록 합니다.

우선 답을 적어 버튼을 누르면 쓰고잇던 박스와 버튼은 사라지도록 [선택자변수.style.display] 사용하여 none으로 만들고 정답과 팁이 나오도록 [선택자변수.style.display]을 block으로 줍니다. 

 

그후 정답이라면 class에 like을 넣을 수있도록 class.add()함수를 사용하여 넣고 거기에 like를 넣습니다.

dislike는 지우는 것으로 코드를 적습니다.

만약 오답이라면 반대로 dislike가 넣어지고 like가 지워지도록 코드를 적습니다.

 

하지만 이때 띄여쓰기를 앞에 붙이게 되면 정답도 오답이되는 오류가 있습니다.

이럴땐 const userAnswer = quizAnswerInput.value.trim();을 사용하여 이러한 오류를 잡습니다.

이때 trim은 메소드로 문자열에서 양쪽 끝에 잇는 공배을 제거하는 기능을 합니다.

value는 input요소에서 입력한 갓을 가져오거나 설정하는데 사용하고 있습니다.

 

 

innerTexttextContent의 차이

두 속성 모두 내부 텍스트를 반환하거나 설정하는데 사용되는 속성입니다.

하지만 차이점음 있습니다.

innerText는 내부의 숨겨진 스타일을 반환하지 않으므로  출력하는데 계산이 불필요해져서 속도가 느립니다.

textContent는 내부의 숨겨진 스타일까지 반환하여 출력하는 속도는 느리지만 더 정확합니다.