본문 바로가기
CodeIt_Sprint/JavaScript_중급

(12)JavaScript중급_4_이벤트 활용_Input태그관련 이벤트

by 코잼민 2024. 11. 15.

#알아야 할 개념 :

● 개념_1 : Input_Focus 관련 event.type , event.프로퍼티

○ 정의 :Input 태그가 마우스 포인터로 눌러 Focus 된 상태에 관한 기본적인 event.type.

- event.type (4가지 : 2 + 2)

○ Form 태그를 요소노드로 했을 시, 

  • Focus됐을 때,  : 'focusin'
  • Focus가 풀렸을 시 : 'focusout'

○ 해당 Input 태그를 요소노드로 했을 시, 

  • Focus됐을 때,  : 'focus'
  • Focus가 풀렸을 시 : 'blur'

※왜저렇게 차이를 두었을까? => 'focus'와 'blur'는 Input 태그에 더 세부적인 기능, 동작을 적용시에 활용법 같다.

● 개념_2 : Input 입력 관련 event.type , event.프로퍼티 (≠ 'keydown' || 'keypress' || 'keyup' )

  • 입력중일 시,  : 'input'
  • Input.value값이 변했을 시 : 'change'

※ 'change' 대하여, //입력중인 도중에 발생되는 event.type이 아니다.

- 상황1 : focus가 되기전 input.value 와 focus가 풀리고 난후 input.value값을 비교하여, 발생한다.

- 상황2 : 입력 중 Enter 누를 시, input.value값 비교

● 개념_3 : 'input' vs  'keydown' || 'keypress' || 'keyup'

  • 'input' : Input.value가 변하는 key들에 대한 event 발생이다.
  • 'keydown' || 'keypress' || 'keyup' : 입력 동시에 발생

 

※연습문제  :

 문제 조건 :

실습 설명

산성비라는 게임을 아시나요? 마치 비처럼 하늘에서 바닥으로 천천히 단어가 떨어지는데 시간이 지날수록 점점 더 속도가 빨라집니다. 그리고 사용자가 입력창에서 그 단어를 입력하면 사라지죠. 최대한 빨리 입력해서 단어가 바닥에 닿지 않도록 하는 타자 연습 게임입니다.

이번 실습에서는 단어가 떨어지는 건 아니지만, 그동안 배운 것들을 활용해서 input 태그에 단어 입력이 완료되면 화면에 있는 단어들이 사라지도록 만들어 봅시다.

단어들을 만드는 로직은 initializer.js에 있는데요. 각 단어가 만들어진 특징을 정리해보면 다음과 같습니다.

  1. ①.  각 단어들은 span 태그로 만들어져 있다.
  2. ②.  각 단어들은 웹 페이지가 갱신될 때마다 랜덤한 위치를 가진다.
  3. ③.  각 단어들은 data-word라는 속성을 가지고 값은 그 단어를 담고 있다.
  4. ④.  각 단어들은 div#container 태그의 자식 태그들이다.

위 특징을 활용해서 단어 입력이 완료되면 화면에 있는 단어들이 사라지는 이벤트 핸들러를 만들고, input 태그에 적절한 타입으로 이벤트 핸들러를 등록해 주세요.

이벤트 핸들러가 갖추어야 하는 기능은 다음과 같습니다.

  1. ①.  입력값과 일치하는 단어를 가진 요소가 있으면 그 요소를 삭제해야 한다.
  2. ②.  이벤트 핸들러가 호출되면 input 태그는 매번 초기화되어야 한다.
  3. ③.   단어를 삭제했다면 checker 함수가 호출되어야 한다.

 Default 코드 :

<!DOCTYPE html>
<html lang="ko">

<head>
  <meta charset="UTF-8">
  <title>Codeit Acid Rain</title>
  <style>
    * {
      box-sizing: border-box;
    }

    body {
      display: flex;
      justify-content: center;
      align-items: center;
      height: 100vh;
      margin: 0;
      padding: 0;
      background-image: url('imgs/background.jpg');
      background-size: cover;
      background-repeat: no-repeat;
    }

    #container {
      position: relative;
      width: 90%;
      height: 80%;
      box-shadow: 0 0 15px 1px #3b3b41;
      background-color: rgba(10, 10, 10, 0.3);
      border-radius: 15px;
    }

    #input {
      width: 180px;
      height: 45px;
      position: absolute;
      bottom: 0;
      left: 50%;
      padding: 10px;
      transform: translateX(-50%);
      font-size: 16px;
      border: none;
    }

    .word {
      position: absolute;
      color: #ffffff;
      font-size: 20px;
      font-weight: 500;
    }
  </style>
</head>

<body>
  <div id="container">
    <input id="input" type="text" placeholder="단어를 입력하세요.">
  </div>
  <script>
    const words = ['Codeit', 'JavaScript', 'DOM', 'document', 'window', 'Event', 'Bubbling', 'Delegation'];
    const container = document.querySelector('#container');

    function getRandomInt(minimum, maximum) {
      const min = Math.ceil(minimum);
      const max = Math.floor(maximum);

      return Math.floor(Math.random() * (max - min)) + min;
    }

    function init() {
      const maxPositionX = container.offsetWidth - 90;
      const maxPositionY = container.offsetHeight - 100;

      for (let word of words) {
        const span = document.createElement('span');
        span.classList.add('word');
        span.style.top = `${getRandomInt(20, maxPositionY)}px`;
        span.style.left = `${getRandomInt(20, maxPositionX)}px`;
        span.dataset.word = word;
        span.textContent = word;
        container.append(span);
      }
    }

    init();
  </script>
  <script>
    const input = document.querySelector('#input');

    function checker() {
      const words = document.querySelectorAll('.word');
      if (words.length === 0) {
        alert('Success!👏');
        if (confirm('retry?')) {
          window.location.reload();
        }
      }
    }

  </script>
</body>

</html>

● 풀이과정 :

알아야 할 개념 :

※특정 태그의 data-속성명의 값으로 요소노드 갖고와 저장하는 방법 (처음 보는 기법임)

const node = document.querySelector(`data-속성명 = "${문자열값}"`);

● 풀이과정 :

웹페이지 출력창에 보이는 단어를 F12를 눌러 태그 관찰을 해보면, 아래와 같다.

<span class="word" data-word="JavaScript" style="top: 137px; left: 228px;">JavaScript</span>

특징 :
- data-word의 속성값 : 단어

- textContent = 단어값

=> data-word의 속성값으로 한방에 노드 끌어들이기 : const 변수 = document.queryselector('[data-word = "${input.value}"]');

=> 반환값 : 일치한다면, 그 단어에 대한 요소노드가 저장됨 , 일치하지 않는다면, null값이 반환

제대로된 요소노드가 저장됐는지 검사

=> if조건문

=> 배열에서 삭제 remove() 

=> 게임 끝인지 검사 checker()

=>input창의 텍스트값 다 지우기

input.addEventListener('change',function(event){
      const word = document.querySelector(`[data-word="${input.value}"]`);

      //입력창에 입력된 값이 배열에 똑같은 값이 존재한다면, 
      //word에 유효한 값이 저장 될 것이다.
      
      if(word)//word가 유효한 값이라면,
      {
        word.remove();
        checker();
      }

      input.value='';
    });