본문 바로가기

FrontEnd/Javascript

제로초 baseball Toy project 학습내용

보통이렇게 form과 input태그가 함께 쓰이면 form태그에 evnet를 추가하여 줌. 그래서 아래 코드에$form.addEventListener("submit", (event) => { });와 같이 코딩한 것임. 사실 form 태그 없이 input만 써도 되긴합니다. 하지만 html의 웹표준을 준수하려고 form안에 input태그를 사용해 준것입니다. 버튼(click)과 달리 form태그는 submit이라는 이벤트가 존재합니다. 이렇게 해서 form안에 있는 button을 누르게 되면 submit이 호출되게 됩니다.

기본적으로 아래와 같은 주소(~.html)였다.

그런데 확인 버튼을 누르면 화면이 깜빡거리는 동시에 이 주소가

로 바뀌는 것을 볼수있다(뒤에 ? 가 덧붙음). 이것이 바로 form 의 기본동작이라는 것입니다. form은 submit할때(form태그안에 있는 button을 눌렀을때)페이지가 새로고침 되는 현상이 존재합니다. 이것은 어떠한 버그가 아니라 form태그를 사용하면 form이 서버로 데이터를 전송하고 다시 돌려받는 기본동작(Default동작)을 수행하게 되는데 새로고침과 다름 없는 효과가 발생하게 되는 것입니다!!! 이러한 기본동작을 우리가 인위적으로는 없앨수 없기 때문에 이 기본동작을 취소하는 방법을 사용합니다. 그것이 바로   event.preventDefault();  라는 코드입니다. 새로 고침되면 선언해 두었던 변수에 저장된 데이터가 모두 날라갑니다. 그것을 막기 위한 방법이 event.preventDefault();입니다!!

event.preventDefault() ==>>기본동작 막기!

eventPreventDefault는 <a> 태그를 대상으로도 사용할 수 있습니다. 즉 태그를 눌러서 해당페이지로 바뀌는 것을 막아줌. 이처럼 <form> 과 <a>태그는 기본적으로 가지고 있는 동작(Default동작)이 있는데 이것을 막아줄때 preventDefault()가 쓰이게 되는 것!

다음으로, 왜 input태그가 아닌 굳이 form태그에 이벤트를 달아주었을까($form.addEventListener)? 그 이유는 form태그에 event를 달아주고 버튼을 눌렀을때 생성되는 event객체로 부터 form태그 안에 있는 input태그 라던가 button태그에 event객체의 속성을 이용하여 접근할 수 있기 때문이다. 예를들어 event.target[0].value는 input태그에 입력되 있는 값을 가져올 수 있는 event객체의 속성이자 식별자의 역할을 하고 event.target[1]같은 경우는 button에 접근할 수 있는 event객체의 속성이자 식별자의 역할을 하게 되는 것이다.

아래는 이 코드의 결과물
event객체의 attribute들

 

JS의 경우 배열을 문자열로 바꾸는 메서드가 join이다. 예를들어 arr=[1,2,3,4]의 배열을 arr.join("")를 하면 1234 로 바뀌게 된다. join의 default값은 쉼표( , )이다. 따라서 arr.join(',')를 하면 그대로 [1,2,3,4]가 나오게 됨.

반면 문자열을 배열로 만들어주는 메서드는 split이다.

split('')은 빈문자열임.

배열 ==>> 문자열  join("")

문자열==>> 배열  split("")

 

<html>
  <head>
    <meta charset="utf-8" />
    <title>숫자야구</title>
  </head>
  <body>
    <!-- 보통이렇게 form과 input태그가 함께 쓰이면 form태그에 evnet를 추가하여 줌. 그래서 아래 코드에 
      $form.addEventListener("submit", (event) => { });와 같이 코딩한 것임.
      사실 form 태그 없이 input만 써도 되긴합니다. 하지만 html의 웹표준을 준수하려고 form안에 input태그를 사용해 준것입니다.
      버튼(click)과 달리 form태그는 submit이라는 이벤트가 존재합니다. 이렇게 해서 form안에 있는 button을 누르게 되면 submit이 호출되게 됩니다.
      
 
-->
    <form id="form">
      <input type="text" id="input" />
      <button>확인</button>
    </form>
    <div id="logs"></div>
    <script>
      $form = document.querySelector("#form");
      $input = document.querySelector("#input");
      $log = document.querySelector("#logs");

      const numbers = [];
      for (let i = 0; i < 9; ++i) {
        numbers.push(i + 1);
      }

      let answer = [];
      for (let i = 0; i < 4; ++i) {
        const index = Math.floor(Math.random() * numbers.length);
        answer.push(numbers[index]);
        numbers.splice(index, 1);
      }
      console.log(answer);
      const tries = [];

      function checkWord(value) {
        if (value.length != 4) {
          return alert("길이가 4인 숫자를 입력하여 주세요");
        } else if (new Set(value).size != 4) {
          return alert("각기 다른 숫자를 입력하여 주세요");
        } else if (tries.includes(value)) {
          return alert(
            "이전에 입력했던 숫자입니다. 다른 숫자를 입력하여 주세요"
          );
        }
        return true;
      }

      //numbers, answer
      $form.addEventListener("submit", (event) => {
        console.log('서브밋',event);
        event.preventDefault();
        const value = $input.value;
        $input.value = "";
        if (!checkWord(value)) {
          // value가 기본조건을 만족하지 않으면 바로 return
          return;
        }
        if (answer.join("") == value) {//JS의 경우 배열을 문자열로 바꾸는 메서드가 join입니다.
          //정답의 경우
          $log.textContent = "홈런입니다!!";
          return;
        }
        if (tries.length >= 9) {
          //실패의 경우
          // $log.textContent='패배, 정답은 ${answer.join}'  //이렇게 $log.textContent는 변수를 넣을 수 없어서 아래와 같이 노드를 만들고
          //그것을 div태그($log)에 붙임.  하지만 굳이 노드를 만들지 않고 달랑 메시지만 인자로 넣어줘도 됨
          const message = document.createTextNode(
                        `패배, 정답은 ${answer.join("")} 입니다`
          );
          $log.appendChild(message);
          return;
        }
        let strike = 0;
        let ball = 0; //정답도 실패도 아닌 경우. strike, ball정보를 알려주고 끝낸다.
        for (let i = 0; i < 4; ++i) {
          let idx = value.indexOf(answer[i]);
          if (idx > -1) {
            if (i == idx) {
              strike += 1;
              continue;
            }
            ball += 1;
          }
        }
        //
    
        $log.appendChild(document.createTextNode(`${value}: ${strike}Strike, ${ball}Ball 입니다`));   
        $log.appendChild(document.createElement("br"));
        //위의 두 문장을 아래와 같이 하나의 문장으로 해 줄 수 있음
        // $log.append(`${value}: ${strike}스트라이크, ${ball}볼 입니다`,document.createElement("br"));
        tries.push(value);
        console.log(tries);
    });
    </script>
  </body>
</html>