[JavaScript] event

유얌얌·2023년 10월 26일
0

JavaScript

목록 보기
2/30

💛 이벤트

💚 event 개요


  • 웹에서 이벤트를 통해 특정 동작을 수행 !

✔ event

  • 무언가 일어났다는 신호, 사건
  • 모든 DOM 요소는 이러한 event를 만들어냄

✔ event object

  • DOM에서 이벤트가 발생했을 때 생성되는 객체
  • 이벤트 종류
    • mouse, input, keyboard,...
    • MDN 문서 참조

💚 event handler


  • DOM 요소는 event를 받고 받은 event를 처리(event handle)할 수 있음

✔ event handler (이벤트 처리기)

  • 이벤트가 발생했을 때 실행되는 함수
  • 사용자의 행동에 어떻게 반응할지를 JavaScript 코드로 표현한 것

✔ .addEventListener()

  • 대표적인 이벤트 핸들러 중 하나

  • 특정 이벤트를 DOM 요소가 수신할 때마다 콜백함수를 호출

  • EventTarget.addEventListener(type, handler)

    • 대상type특정 Event가 발생하면, 지정한 이벤트를 받아 할 일을 등록한다
    • EventTarget
      • DOM 요소
    • type
      • 수신할 이벤트
      • 문자열로 작성(ex.'click'), MDN문서에 있는 것
      • 클릭 이벤트, 인풋 이벤트 등등 어떤 이벤트인지
    • handler
      • 발생하는 이벤트 객체를 수신하는 콜백 함수
      • 콜백함수는 발생한 Event object를 유일한 매개변수로 받음
  • 요소에 addEventListener를 부착하게 되면 내부의 this값은 대상 요소를 가리키게 됨

    • event 객체의 currentTarget 속성 값과 동일

❗ addEventLister에서 화살표 함수 주의사항 - 화살표 함수는 자신만의 this를 가지지 않기 때문에 (자신을 포함하고 있는 상위 함수의 this를 상속받음) this 값을 사용할 때는, 화살표 함수 쓰지 않기

✔ addEventListener 활용

  • 버튼을 클릭하면 버튼 요소 출력하기
  • 버튼에 이벤트 처리기를 부착 ->
    클릭 이벤트가 발생하면 ->
    이벤트가 발생한 버튼 정보를 출력

✔ addEventListener의 콜백 함수 특징

  • 발생한 이벤트를 나타내는 Event 객체를 유일한 매개변수로 받음
  • 아무것도 반환하지 않음

💚 버블링 (Bubbling)


  • 한 요소에 이벤트가 발생하면, 이 요소에 할당된 핸들러가 동작하고, 이어서 부모 요소의 핸들러가 동작하는 현상
  • 가장 최상단의 조상 요소(document)를 만날 때까지 이 과정이 반복되면서 요소 각각에 할당된 핸들러가 동작
  • 이벤트가 제일 깊은 곳에 있는 요소에서 시작해 부모 요소를 거슬러 올라가며 발생하는 것이 마치 물속 거품과 닮음

✔ 'target' & 'currentTarget'속성

  • 이벤트가 정확히 어디서 발생했는지 접근할 수 있는 방법

    • event.target
    • event.currentTarget

  • 'target' 속성

    • target은 실제 이벤트가 발생한 요소
      • click이벤트라면, 실제 click이 일어난 요소
    • 이벤트가 발생한 가장 안쪽의 요소(target)을 참조하는 속성
    • 버블링이 진행 되어도 변하지 않음
  • 'currentTarget' 속성

    • curentTarget은 핸들러가 부착된 요소
    • 항상 이벤트 핸들러가 연결된 요소만을 참조하는 속성
    • 현재 요소
    • currentTarget은 this랑 같음
    • 이벤트가 버블링해서 올라가서 발생

✔ 특징

  • 핸들러는 부모 요소에 하나밖에 없어도, 그 부모의 자식 요소에서 발생하는 이벤트를 잡아낼 수 있음
  • 버블링 되어서 핸들러를 실행시키기 때문
  • 그래서 자식요소에 하나하나 핸들러를 붙일 필요 없이, 상위 부모요소 하나에만 핸들러를 붙여도 돼!

💛 event handler 활용

1. click 이벤트 실습

✔ 버튼을 클릭하면 숫자를 1씩 증가

  <button id="btn">버튼</button>
  <p>클릭횟수 : <span id="counter">0</span></p>
// 1. 초기값 할당
    let counterNumber = 0

    // 2. 버튼 요소 선택
    const btn = document.querySelector('#btn')

    // 3. 콜백 함수 (버튼에 클릭 이벤트가 발생할때마다 실행할 코드)
    const clickHandler = function () {
      // 3.1 초기값 += 1
      counterNumber += 1

      // 3.2 span 요소를 선택
      const spanTag = document.querySelector('#counter')

      // 3.3 p 요소의 컨텐츠를 1 증가한 초기값으로 설정
      spanTag.textContent = counterNumber
    }

    // 4. 버튼에 이벤트 핸들러 부착 (클릭 이벤트)
    btn.addEventListener('click', clickHandler)

2. input 이벤트 실습

✔ 사용자의 입력 값을 실시간으로 출력

<body>
  <input type="text" id="text-input">
  <p></p>

  <script>
    // 1. input 요소 선택
    const inputTag = document.querySelector('#text-input')
    // 2. p 요소 선택
    const pTag = document.querySelector('p')
    // 3. 콜백 함수 (input 요소에 input 이벤트가 발생할때마다 실행할 코드)
    // 3.1 작성하는 데이터가 어디에 누적되고 있는지 찾기
    const inputHandler = function (event) {
      // console.log(event)
      // console.log(event.currentTarget)
      console.log(event.currentTarget.value)
      console.log(this.value)
    
    // 3.2 p요소의 컨텐츠에 작성하는 데이터를 추가
      pTag.textContent = event.currentTarget.value //  이거를 변수에 담아서 넘겨도 되고, 이렇게 써도 되고
    }
      // 4. input 요소에 이벤트 핸들러 부착 (input 이벤트)
    inputTag.addEventListener('input', inputHandler)  // input 이벤트가 발생할 때
  </script>
</body>

❗ currentTarget 주의사항

  • console.log()로 event 객체를 출력할 경우, currentTarget키의 값은 null을 가짐
  • currentTarget은 이벤트가 처리되는 동안에만 사용할 수 있기 때문
  • 대신 console.log(event.currentTarget)을 사용하면 콘솔에서 확인 가능
  • currentTarget 이후의 속성 값들은 target을 참고해서 사용하기 (currentTarget.~~ (X))

3. click & input 이벤트 실습

✔ 사용자의 입력 값을 실시간으로 출력 + 버튼을 클릭하면 출력한 값의 CSS 스타일을 변경하기

<body>
  <h1></h1>
  <button id="btn">클릭</button>
  <input type="text" id="text-input">

  <script>
    // input 구현
    const inputTag = document.querySelector('#text-input')
    const h1Tag = document.querySelector('h1')

    const inputHandler = function (event) {
      h1Tag.textContent = event.currentTarget.value
    }

    inputTag.addEventListener('input', inputHandler)

    // click 구현
    const btn = document.querySelector('#btn')


    const clickHandler = function (event) {
      // console.log(event)
      // h1Tag.classList.add('blue')  // class 추가 (ex.다크모드)

      // toggle
      h1Tag.classList.toggle('blue')  // 토글쓰면 복잡하게 if 안써도돼
    }

    btn.addEventListener('click', clickHandler)

  </script>
</body>

4. todo 실습

✔ 빈 문자열 입력 방지, 입력이 없을 경우 경고창 띄움

<body>
  <input type="text" class="input-text">
  <button id="btn">+</button>
  <ul></ul>

  <script>
    // 1. 필요한 요소 선택
    const inputTag = document.querySelector('.input-text')
    const btn = document.querySelector('#btn')
    const ulTag = document.querySelector('ul')

    const addTodo = function (event) {
      // 2.1 사용자 입력 데이터 저장
      const inputData = inputTag.value  // event.currentTarget.value라고하면 이 event는 클릭 이벤트 인자라서 안됨

      // 3. 사용자 입력 데이터가 빈 데이터인지 확인
      if (inputData.trim()) {  // 문자열에 공백 제거

        // 2.2 데이터를 저장할 li 요소를 생성
        const liTag = document.createElement('li')
        // console.log(liTag)

        // 2.3 li 요소 컨텐츠에 데이터 입력
        liTag.textContent = inputData
        // console.log(liTag)

        // 2.4 li 요소를 부모 ul 요소의 자식 요소로 추가
        ulTag.appendChild(liTag)

        // 2.5 todo 추가 후 input의 입력 데이터는 초기화
        inputTag.value = ''
      } else {
        alert('투두를 입력하세요')
      }
    }
    // 2. 버튼에 이벤트 핸들러를 부착
    btn.addEventListener('click', addTodo)


  </script>
</body>

5. 로또 번호 생성기 실습

✔ lodash 라이브러리 사용

<body>
  <h1>로또 추천 번호</h1>
  <button id="btn">행운 번호 받기</button>
  <div></div>

  <script src="https://cdn.jsdelivr.net/npm/lodash@4.17.21/lodash.min.js"></script>
  <script>
    // 1. 필요한 요소 선택
    const btn = document.querySelector('#btn')
    const divTag = document.querySelector('div')

    // 2. 로또 번호를 생성하는 함수 | 태그를 만들고 출력까지하는 (콜백함수)
    const getLottery = function (event) {
      // 2.1 1부터 45까지의 값이 필요
      const numbers = _.range(1, 46)
      // console.log(numbers)

      // 2.2 45개의 요소가 있는 배열에서 6개 번호 추출
      const sixNumbers = _.sampleSize(numbers, 6)
      // console.log(sixNumbers)

      // 2.5 6개의 li 요소를 담을 ul 요소 생성
      const ulTag = document.createElement('ul')

      // 2.3 추출한 번호 배열을 "반복"하면서 li 요소를 생성 (배열반복 -> forEach)
      sixNumbers.forEach(function (number) {

      // 2.4 번호를 담을 li 요소 생성 후 입력
        const liTag = document.createElement('li')
        liTag.textContent = number
        // console.log(liTag)

      // 2.6 만들어진 li를 ul 요소에 추가
        ulTag.appendChild(liTag)
        console.log(ulTag)
      })

      // 2.7 완성한 ul 요소를 div 요소에 추가
      // 반복이 끝난 이후에!
      divTag.appendChild(ulTag)
    }

    // 3. 버튼 요소에 이벤트 핸들러를 부착
    btn.addEventListener('click', getLottery)
  </script>
</body>
  • lodash
    • 모듈성, 성능 및 추가 기능을 제공하는 자바스크립트 유틸리티 라이브러리
    • array, object 등 자료구조를 다룰 때 사용하는 유용하고 간편한 함수들을 제공
    • https://lodash.com/

💚 이벤트 기본 동작 취소

✔ .preventDefault()

  • 해당 이벤트에 대한 기본 동작을 실행하지 않도록 지정
  • ex) a태그를 누르면 해당링크로 가는 행동을 하는데, 이 행동을 할 수 없게 !
  • 전파를 막는 것이 아니라, 기본 동작을 실행할 수 없게 하는 것
    • 복사를 못하게 한다던가, form 제출 시 새로고침 동작을 취소한다던가..
<body>
  <h1>중요한 내용</h1>

  <form id="my-form">
    <input type="text" name="username">
    <button type="submit">Submit</button>
  </form>

  <script>
    // 1
    const h1Tag = document.querySelector('h1')

    h1Tag.addEventListener('copy', function (event) {
      console.log(event)
      event.preventDefault()
      alert('복사 할 수 없습니다.')
    })

    // 2
    const formTag = document.querySelector('#my-form')

    const handleSubmit = function (event) {
      event.preventDefault()
    }

    formTag.addEventListener('submit', handleSubmit)

  </script>
</body>
profile
조금씩이라도 꾸준하게

0개의 댓글

관련 채용 정보