기초부터 시작하는 코딩/Javascript

Javascript를 이용한 사이트 만들기! - 퀴즈 효과 사이트 만들기03

kebab00 2023. 3. 14. 13:20

728x90

- 자 오늘은 2번에 있는 문제들을 여러 개가 있는 사이트를 만들어 보겠습니다.

- 완성본 입니다.

- 기본적인 HTML태그들은 문제가 있는 태그인 <div class="quiz"> 가 3개로 늘어난 것 말고는 달라진 것이 없습니다.

- 그래서 script부분만 보도록 하겠습니다.

<script>
    // 선택자
    const quizWrap = document.querySelector(".quiz__wrap");
    const quizTitle = quizWrap.querySelectorAll(".quiz__title");  // 시험 종목&시간
    const quizQuestionNum = quizWrap.querySelectorAll(".qiuz__question em"); //문제 번호
    const quizQuestion = quizWrap.querySelectorAll(".qiuz__question span") // 문제 질문
    const quizAnswerResult = quizWrap.querySelectorAll(".quiz__answer .result");    // 문제 정답
    const quizDesc = quizWrap.querySelectorAll(".quiz__desc") // 문제 해설
    const quizAnswerConfirm = quizWrap.querySelectorAll(".quiz__answer .confirm"); //정답버튼
    const quizAnswerInput = quizWrap.querySelectorAll(".quiz__answer .input");     // 사용자 정답
    const dogWrap = quizWrap.querySelectorAll(".dog__wrap");


    // 문제 정보 
    const quizInfo = [
        {
            infoType : "정보처리기능사" ,
            infoTime : "2011년 4회" ,
            infoNumber : "1",
            infoQuestion : "주파수분할 다중화 방식에서 각 채널간 간섭을 막기 위해서 일종의 완충지역 역할을 하는 긋을 무엇이라고 하는가?",
            infoAnswer : "가드밴드",
            infoDesc : "가드밴드(Guard band)는 무선 통신에서 사용되는 용어입니다. 무선 주파수 대역을 분할하여 서로 다른 통신 시스템이 동시에 사용할 수 있도록 하기 위해, 각각의 주파수 대역 사이에 일정한 간격을 두어 사용하지 않는 주파수 대역을 만드는 것을 의미합니다.",
        },{
            infoType : "정보처리기능사" ,
            infoTime : "2011년 4회" ,
            infoNumber : "2",
            infoQuestion : "사용자의 명령으로 시스템이 수행되고 그에 따른 결과를 나타내는 대화식 운영체제는 무엇인가?",
            infoAnswer : "UNIX",
            infoDesc : "UNIX는 다중 사용자, 다중 작업(multiuser, multitasking) 운영 체제(OS)로, AT&T 벨 연구소(Bell Labs)의 켄 톰슨(Ken Thompson)과 데니스 리치(Dennis Ritchie) 등이 개발한 운영 체제입니다. 초기에는 주로 대형 컴퓨터나 서버 시스템에서 사용되었으나, 현재는 다양한 장비에서 사용되는 범용 운영 체제가 되었습니다.",
        },{
            infoType : "정보처리기능사" ,
            infoTime : "2011년 4회" ,
            infoNumber : "3",
            infoQuestion : "프로세스들이 서로 다른 프로세스가 차지하고 있는 자원을 무한정 기다려 시스템이 멈춘 것처럼 보이는 상태는 무엇인가?",
            infoAnswer : "교착상태",
            infoDesc : "교착상태(Deadlock)는, 여러 개의 프로세스 또는 스레드가 서로 상대방의 자원을 기다리며 무한정 대기하는 상황을 말합니다. 이 상태에서는 어떤 프로세스나 스레드도 진행하지 못하고, 전체 시스템의 작동이 멈춥니다.",
        }
    ];

    // 문제 출력
    quizInfo.forEach(function(e, i){
        quizTitle[i].innerHTML = quizInfo[i].infoType + " " + quizInfo[i].infoTime;
        quizQuestionNum[i].textContent = quizInfo[i].infoNumber;
        quizQuestion[i].textContent = quizInfo[i].infoQuestion;
        quizAnswerResult[i].textContent = quizInfo[i].infoAnswer;
        quizDesc[i].textContent = quizInfo[i].infoDesc;
    })

    // 정답 숨기기
    quizInfo.forEach((e, i) => {
        quizAnswerResult[i].style.display = "none";
        quizDesc[i].style.display = "none";
    });

    // 정답 학인

    quizAnswerConfirm.forEach(function(btn, num){
        btn.addEventListener("click",function(){
            // 사용자 정답을 가져오는 방법 o
            const userAnswer = quizAnswerInput[num].value.trim();
            quizAnswerInput[num].style.display = "none"; // 인풋 박스 숨김
            quizAnswerConfirm[num].style.display = "none"; // 정답 확인 버튼 숨김
            quizAnswerResult[num].style.display = "block"; // 정답 나타내기
            quizDesc[num].style.display = "block"; // 해설 보이기
            // 사용자 정답 == 문제 정답
            if(userAnswer == quizInfo[num].infoAnswer){
                dogWrap[num].classList.add("like");
            }else{
                dogWrap[num].classList.add("dislike");
            }
            ;
        });
    });

</script>

- 차이점이 보이시나요??  여러 개를 만들 때 가장 큰 차이점은 바로 선택자를 만들 때 querySelector가 아닌 querySelectorAll을 사용한다는 점입니다.

- 그렇기 때문에 선택자를 입력할 때도 몇 번째 선택자인지 "[]"안에 번호를 넣어서 선택을 해주어야 합니다.(가장 많이 한 실수 ㅎㅎ;;)

- 선택자의 종류 자체는 2번과 같습니다!! 아!! 종목과 횟수가 나누어져 있던 것을 하나로 합쳐주었어요!!

- 문제가 3가지이니까 내용도 3개 여야겠죠!! 그래서 quizInfo를 배열로 만들어주어 그 안에 객체를 3개 만들고 각 객체 안에 시험정보 및 문제 정보들을 넣어주었습니다.

- 문제가 3개인데 그렇다고 똑같은 명령을 3번 할 수는 없으니 반복문인 forEach를 써주었습니다.

  // 문제 출력
    quizInfo.forEach(function(e, i){
        quizTitle[i].innerHTML = quizInfo[i].infoType + " " + quizInfo[i].infoTime;
        quizQuestionNum[i].textContent = quizInfo[i].infoNumber;
        quizQuestion[i].textContent = quizInfo[i].infoQuestion;
        quizAnswerResult[i].textContent = quizInfo[i].infoAnswer;
        quizDesc[i].textContent = quizInfo[i].infoDesc;
    })

- forEach문 안에 있는 function에서는 첫 번째는 element, 두 번째는 index, 세 번째는 array를 뜻합니다.

- 저희는 quizInfo의 index가 필요하니 두 번째까지 적어주었습니다.

- 그 안에 입력할 내용들을 넣어주면 끝!! 일단 문제 출력은 끝이 났습니다.

   // 정답 학인

    quizAnswerConfirm.forEach(function(btn, num){
        btn.addEventListener("click",function(){
            // 사용자 정답을 가져오는 방법 o
            const userAnswer = quizAnswerInput[num].value.trim();
            quizAnswerInput[num].style.display = "none"; // 인풋 박스 숨김
            quizAnswerConfirm[num].style.display = "none"; // 정답 확인 버튼 숨김
            quizAnswerResult[num].style.display = "block"; // 정답 나타내기
            quizDesc[num].style.display = "block"; // 해설 보이기
            // 사용자 정답 == 문제 정답
            if(userAnswer == quizInfo[num].infoAnswer){
                dogWrap[num].classList.add("like");
            }else{
                dogWrap[num].classList.add("dislike");
            }
            ;
        });
    });

- 자 이제 정답을 확인하는 법을 알아보겠습니다.

- 이것도 forEach문을 통해 3번 반복하게 해 주었습니다.

- element를 btn이라고 하고 index를 num이라고 해주고 각 btn를 누르면 함수가 실행되도록 해주었습니다.

- 그 후 각 선택자들을 출력하는데 선택자[num]이라고 해주어 각 선택자들이 num번째라고 알려주었습니다.

- 이렇게 하면 각 문제에 해당하는 인포박스, 정답확인버튼등 필요한 것들을 나타내고 숨겨주었습니다.

- 그리고 정답을 맞혀을 때와 틀렸을 때 강아지도 선택자 뒤에 [num]을 넣어주어 번호에 맞게 효과를 넣어주었습니다.