[Let's get it 자바스크립트 프로그래밍] - 3.1~3.9 DOM 객체 다루기_끝말잇기 게임

신혜린·2024년 12월 24일
0
post-thumbnail

끝말잇기가 어떻게 진행되는가?

  1. 프로그램 절차의 개수는 정해져 있어야 한다.
  2. 각 절차는 항상 같은 내용이어야 한다.
  3. 모든 가능성을 고려해야 한다.
  4. 예시는 절차를 검증하는 데 사용한다.

1️⃣ 1차 순서도


사진 출처: Let's Get IT 자바스크립트 프로그래밍 (2) 끝말잇기 게임

🔘 시작과 끝은 두 겹의 원 기호로 표시
⚪️ 일반적인 절차는 타원형
🔷 판단을 요구하는 절차는 마름모

프로그램의 절차를 세울 땐 항상 일직선으로 진행되지는 않는다.

  • 위와 같이 판단 결과에 따라 가지치기가 발생하는 지점🔷을 분기점 이라고 한다.

순서도(절차)는 프로그래밍을 진행하면서 점차 보완해나간다.


html

<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8">
    <title>끝말잇기</title>
  </head>
  
  <body>
    <div><span id="order">1</span>번째 참가자</div>
    <div>제시어: <span id="word"></span></div>
    <input type="text">
    <button>입력</button>
    <script>
      // script가 작성될 곳
    </script>
  </body>
</html>

html을 통해 화면을 그린다.
css를 통해 화면을 꾸민다.
script 태그를 통해 javascript 코드를 작성한다.

  • html은 위에서부터 아래로 실행되므로, 화면을 그리는 태그들이 먼저 실행돼서 화면이 그려져야 script 태그에서 자바스크립트로 화면을 조작할 수 있다.
  • 즉, script 태그는 htmlbody 태그 내 최하단에 있어야한다.

자바스크립트로 프로그램 조작하기

<script>
  const number = Number(propmt('몇 명이 참가하나요?'));
  const $button = documnet.querySelector('button');
  const $input = documnet.querySelector('input');
  const $word = document.querySelector('#word');

  const onClickButton = () => {
  };
  const onInput = () => {
  };

  $button.addEventListener('click', onClickButton);
  $input.addEventListener('input', onInput);
</script>

prompt

  • prompt대화 상자를 띄우는 함수로, 사용자의 입력을 기다린다.
  • prompt로 입력 받은 데이터는 문자열이므로, 위 코드에서 숫자 타입으로 변환한다. (Number(propmt('몇 명이 참가하나요?'))
  • 사용자로부터 입력 받은 값을 number 변수에 저장한다.

querySelector

  • html 태그 내 특정 요소를 선택할 때 사용한다.
  • buttoninput 요소를 가져와 각각 $button$input 변수에 할당한다.
  • # 을 이용해 특정 id 값을 가진 요소를 선택할 수 있다.

이벤트 리스너

  • 이벤트 리스너를 추가해 자바스크립트가 html에서 발생하는 이벤트를 감지할 수 있게 한다.

    태그.addEventListener('이벤트 이름', 리스너 함수)

    • ⭐️ 리스너 함수에 () 를 붙여서 호출하게 되면 이벤트와 상관 없이 자동으로 함수가 실행된다.
  • 'Click' 이벤트가 발생하면 onClickButton 함수를 실행한다.
  • ⭐️ onClickButton과 같이 특정 작업이 실행되고 난 뒤에 추가로 실행되는 함수를 콜백 함수 라고 한다.


2️⃣ 2차 순서도

  • 사용자가 이벤트를 발생시키지 않으면 다음 절차로 넘어가지 않는 경우가 있기 때문에 대기 절차와 입력 버튼 클릭 절차를 추가한다.


3️⃣ 3차 순서도

  • 첫 번째 사용자가 입력한 단어가 제시어가 되므로, 첫 번째 참가자인지 아닌지 판단을 하는 절차가 추가된다.
  • 첫 번째가 아닌 사용자가 입력한 단어는 입력한 단어가 올바른지 판단하는 절차가 실행된다.

    여기서 받은 제시어 값은 word 변수를 생성해서 할당한다.

    let word
    • word 값은 사람들이 단어를 입력할 때마다 바뀌므로 let으로 선언한다.

만약 let 변수가 선언만 되고 초기화되지 않은 경우, 첫 번째 사용자제시어를 주지 않았음을 의미하기 때문에 순서도는 다음과 같이 정의될 수 있다.



4️⃣ 4차 순서도

  • 입력받은 단어를 저장할 변수를 생성한다.

<script>
  const number = Number(propmt('몇 명이 참가하나요?'));
  const $button = documnet.querySelector('button');
  const $input = documnet.querySelector('input');
  const $word = document.querySelector('#word');

  let word; // 제시어
  let newWord; // 현재 단어

  const onClickButton = () => {
    if (!word) { // 제시어가 undefined 인 경우 (undefined는 false한 값)
      word = newWord; // 현재 단어는 제시어가 된다
      $word.textContent = word; // 화면에 제시어를 표시한다
    } else {
      // 제시어가 비어있지 않은 경우
    }
  };

  const onInput = (event) => {
    newWord = event.target.value; // 입력 받은 단어를 현재 단어 값으로 할당한다
  };

  $button.addEventListener('click', onClickButton);
  $input.addEventListener('input', onInput);
</script>

textContent

  • 요소(태그) 내부의 값을 얻거나 수정할 때 사용한다.
  • $word.textContentword라는 id를 가진 요소 값을 할당한 변수 $word를 통해 요소 내부의 값을 불러온다.
  • #word는 처음에 빈 값이므로 $word.textContent 는 빈 문자열 '' 을 불러온다.
  • 입력 받은 제시어 word 를 현재 단어 newWord 에 할당한 뒤,
  • 화면에 그려주기 위해 #word 요소의 내부 값으로 다시 할당한다.

    태그.textContent // 태그 내부의 문자열을 가져옴
    태그.textContent = 값 // 태그 내부의 문자열을 해당 값으로 설정함

event.target.value

  • 특정 리스너가 발생했을 때 콜백 함수의 매개변수로 받은 event를 참고하여 이벤트에 관한 정보를 전달 받는다.
  • event.target.value 를 통해 특정 요소로 입력 받은 값을 불러올 수 있다.


올바른 단어인지 판단하기

문자열은 문자들의 나열을 뜻하므로, 각각의 문자를 분리할 수 있다.

문자열[자릿수]
ex) hello[0] // 'h'

문자열의 마지막 자리는 length를 이용해서 가져올 수 있다.

문자열[문자열.length - 1]
ex) hello.length = 5
hello[5 - 1] === hello[4] // 'o'

  • 인덱스는 0부터 시작하므로 1을 빼서 마지막 인덱스를 구할 수 있다.
<script>
  const number = Number(propmt('몇 명이 참가하나요?'));
  const $button = documnet.querySelector('button');
  const $input = documnet.querySelector('input');
  const $word = document.querySelector('#word');

  let word; // 제시어
  let newWord; // 현재 단어

  const onClickButton = () => {
    if (!word) { // 제시어가 undefined 인 경우 (undefined는 false한 값)
      word = newWord; // 현재 단어는 제시어가 된다
      $word.textContent = word; // 화면에 제시어를 표시한다
    } else {
      // 제시어가 비어있지 않은 경우
      if (word[word.length - 1] === newWord[0]) { 
        // 제시어의 마지막 요소와 입력한 단어의 첫 번째 요소가 일치하는가 판단
        word = newWord // 현재 단어를 제시어에 저장한다
      	$word.textContent = word // 제시어를 화면에 표시한다
      } else {
        // 잘못된 값을 입력 받은 경우
      }
    }
  };

  const onInput = (event) => {
    newWord = event.target.value; // 입력 받은 단어를 현재 단어 값으로 할당한다
  };

  $button.addEventListener('click', onClickButton);
  $input.addEventListener('input', onInput);
</script>


5️⃣ 5차 순서도

  • #order 태그에 저장된 참가자 명수를 고려한 절차를 추가한다.

<script>
  const number = Number(propmt('몇 명이 참가하나요?'));
  const $button = documnet.querySelector('button');
  const $input = documnet.querySelector('input');
  const $word = document.querySelector('#word');
  const $order = document.querySelector('#order'); // 추가

  let word; // 제시어
  let newWord; // 현재 단어

  const onClickButton = () => {
    if (!word) { // 제시어가 undefined 인 경우 (undefined는 false한 값)
      word = newWord; // 현재 단어는 제시어가 된다
      $word.textContent = word; // 화면에 제시어를 표시한다
      const order = Number($order.textContent);
      if (order + 1 > number) {
        $order.textContent = 1;
      } else {
        $order.textContent = order + 1;
      }
    } else {
      // 제시어가 비어있지 않은 경우
      if (word[word.length - 1] === newWord[0]) { 
        // 제시어의 마지막 요소와 입력한 단어의 첫 번째 요소가 일치하는가 판단
        word = newWord // 현재 단어를 제시어에 저장한다
      	$word.textContent = word // 제시어를 화면에 표시한다
        const order = Number($order.textContent);
        if (order + 1 > number) {
          $order.textContent = 1;
        } else {
          $order.textContent = order + 1;
        }
      } else {
        // 잘못된 값을 입력 받은 경우
      }
    }
  };

  const onInput = (event) => {
    newWord = event.target.value; // 입력 받은 단어를 현재 단어 값으로 할당한다
  };

  $button.addEventListener('click', onClickButton);
  $input.addEventListener('input', onInput);
</script>
  • 3명의 참가자가 있으면 number 는 3이 된다.

if (order + 1 > number)

  • 현재 순서(order)가 3이라면 (= #order의 내부 값),
  • 여기에 1을 더한 값은 4로, number 보다 크다.
  • 이 때 현재 순서를 1로 초기화 시키기 위해 $order의 값을 1로 수정해준다. ($order.textContent = 1;)

else

  • 현재 순서(order)가 1이라면 (= #order의 내부 값),
  • 여기에 1을 더한 값은 2로, number 보다 작다.
  • 이 때 다음 순서로 설정하기 위해 $order의 값을 2로 수정해준다.


틀렸을 때 오류 표시

  • alert 함수를 통해 입력한 단어가 올바르지 않다는 것을 표시한다.
<script>
  const number = Number(propmt('몇 명이 참가하나요?'));
  const $button = documnet.querySelector('button');
  const $input = documnet.querySelector('input');
  const $word = document.querySelector('#word');
  const $order = document.querySelector('#order'); // 추가

  let word; // 제시어
  let newWord; // 현재 단어

  const onClickButton = () => {
    if (!word) { // 제시어가 undefined 인 경우 (undefined는 false한 값)
      word = newWord; // 현재 단어는 제시어가 된다
      $word.textContent = word; // 화면에 제시어를 표시한다
      const order = Number($order.textContent);
      if (order + 1 > number) {
        $order.textContent = 1;
      } else {
        $order.textContent = order + 1;
      }
    } else {
      // 제시어가 비어있지 않은 경우
      if (word[word.length - 1] === newWord[0]) { 
        // 제시어의 마지막 요소와 입력한 단어의 첫 번째 요소가 일치하는가 판단
        word = newWord // 현재 단어를 제시어에 저장한다
      	$word.textContent = word // 제시어를 화면에 표시한다
        const order = Number($order.textContent);
        if (order + 1 > number) {
          $order.textContent = 1;
        } else {
          $order.textContent = order + 1;
        }
      } else {
        // 잘못된 값을 입력 받은 경우
        alert('올바르지 않은 단어입니다!');
      }
    }
  };

  const onInput = (event) => {
    newWord = event.target.value; // 입력 받은 단어를 현재 단어 값으로 할당한다
  };

  $button.addEventListener('click', onClickButton);
  $input.addEventListener('input', onInput);
</script>

6️⃣ 6차 순서도

  • UX 편의를 고려하여 추가적인 메소드를 추가한다.

<script>
  const number = Number(propmt('몇 명이 참가하나요?'));
  const $button = documnet.querySelector('button');
  const $input = documnet.querySelector('input');
  const $word = document.querySelector('#word');
  const $order = document.querySelector('#order'); // 추가

  let word; // 제시어
  let newWord; // 현재 단어

  const onClickButton = () => {
    if (!word) { // 제시어가 undefined 인 경우 (undefined는 false한 값)
      word = newWord; // 현재 단어는 제시어가 된다
      $word.textContent = word; // 화면에 제시어를 표시한다
      const order = Number($order.textContent);
      if (order + 1 > number) {
        $order.textContent = 1;
      } else {
        $order.textContent = order + 1;
      }
      $input.value = ''; // 입력창 값을 비우고
      $input.focus(); // 포커싱한다
    } else {
      // 제시어가 비어있지 않은 경우
      if (word[word.length - 1] === newWord[0]) { 
        // 제시어의 마지막 요소와 입력한 단어의 첫 번째 요소가 일치하는가 판단
        word = newWord // 현재 단어를 제시어에 저장한다
      	$word.textContent = word // 제시어를 화면에 표시한다
        const order = Number($order.textContent);
        if (order + 1 > number) {
          $order.textContent = 1;
        } else {
          $order.textContent = order + 1;
        }
      } else {
        // 잘못된 값을 입력 받은 경우
        alert('올바르지 않은 단어입니다!');
        $input.value = ''; // 입력창 값을 비우고
      	$input.focus(); // 포커싱한다
      }
    }
  };

  const onInput = (event) => {
    newWord = event.target.value; // 입력 받은 단어를 현재 단어 값으로 할당한다
  };

  $button.addEventListener('click', onClickButton);
  $input.addEventListener('input', onInput);
</script>

$input.value

입력태그.value // 입력창의 값을 가져옴
입력태그.value = 값 // 입력창에 값을 넣음

$input.focus()

입력태그.focus() // 입력창을 하이라이트



✅ 순서도 최적화하기

  • 가장 기본적인 것은 중복되는 부분을 찾아 최적화하는 것.
판단1판단2결과
제시어가 비어있다입력한 단어가 제시어가 된다
제시어가 비어있다입력한 단어가 제시어가 된다
제시어가 비어있지 않다단어가 올바르다입력한 단어가 제시어가 된다
제시어가 비어있지 않다단어가 올바르지 않다틀렸다고 표시한다

입력한 단어가 제시어가 된다 를 만족시키기 위한 절차를

  • 제시어가 비어있는가입력한 단어가 올바른가 의 절차를 하나로 합쳐
  • 제시어가 비어있거나 || 입력한 단어가 올바른가 로 최적화 할 수 있다.

<script>
  const number = Number(propmt('몇 명이 참가하나요?'));
  const $button = documnet.querySelector('button');
  const $input = documnet.querySelector('input');
  const $word = document.querySelector('#word');
  const $order = document.querySelector('#order'); 

  let word; 
  let newWord;

  const onClickButton = () => {
    if (!word || word[word.length - 1] === newWord[0]) { 
      // 중복 로직 최적화
      word = newWord; 
      $word.textContent = word; 
      const order = Number($order.textContent);
      if (order + 1 > number) {
        $order.textContent = 1;
      } else {
        $order.textContent = order + 1;
      }
      $input.value = '';
      $input.focus()'
    } else {
      alert('올바르지 않은 단어입니다!');
      $input.value = '';
      $input.focus();
    }
  };

  const onInput = (event) => {
    newWord = event.target.value; 
  };

  $button.addEventListener('click', onClickButton);
  $input.addEventListener('input', onInput);
</script>
profile
개 발자국 🐾

0개의 댓글