TIL 05-19 JS Controlling Event - 이벤트 제어하기

김덕협·2026년 5월 19일

TIL

목록 보기
11/43

0. Syntax 2 복습 (Remind)

객체 (Object)

  • 파이썬의 dict와 유사
  • key, value로 구성
  • key문자형만 가능
  • in 연산자 대신 hasOwnProperty()를 사용할 것

this

  • 함수나 메서드를 호출한 객체를 가리키는 키워드 (파이썬의 self)
  • 일반 함수에서 호출: 전역 객체
  • 메서드에서 호출: 호출한 객체
  • ※ 메서드란? 객체 안에서 선언된 함수

콜백 함수

  • 다른 함수로부터 호출되는 함수

Array Method

forEach

arr.forEach(function (item, index, array) {
  // item: 현재 접근하고 있는 인자
  // index: 현재 접근하고 있는 인자의 인덱스
  // array: 접근하고 있는 배열 전체
})
  • 단순 순회용, 반환값 없음

map

arr.map(function (item, index, array) {
  return 데이터
})
  • 원본 배열을 변경하지 않고, 새로운 배열을 반환
  • 원본과 크기가 같은 배열이 생성됨

filter

arr.filter(function (item, index, array) {
  return true or false
})
  • return 값이 true인 애들만 모아 새로운 배열을 생성
  • 원본과 크기가 같거나 작은 배열이 생성됨

reduce

arr.reduce(function (acc, cur, index, array) {
  // acc: 이전까지 누적된 값
  // cur: 현재 쳐다보고 있는 값
}, 초기값)
  • 배열을 완전히 다른 형태로 변환할 때 사용
  • ex) 리스트 → 숫자(합), 리스트 → Object

1. Event

Event : 웹 페이지 상에서 무언가 일어났다는 신호 또는 사건

  • 모든 DOM 요소는 다양한 형태의 이벤트를 발생시킬 수 있음
    • button 클릭 → click 이벤트
    • input 값 변경 → input 이벤트 등
  • Event Object : DOM에서 이벤트가 발생하면, 브라우저는 해당 이벤트에 관한 정보를 담은 event object를 자동으로 생성
  • DOM 요소에서 event가 발생하면, 해당 event는 연결된 event handler에 의해 처리됨

2. Event Handler & addEventListener

Event Handler : 특정 이벤트가 발생했을 때 실행되는 콜백 함수

addEventListener()

특정 DOM 요소에, 지정한 이벤트가 발생했을 때 실행할 이벤트 핸들러를 등록하는 메서드

EventTarget.addEventListener(type, handler)
// EventTarget: DOM 요소
// type: 수신할 이벤트
// handler: 핸들러

기본 사용 패턴

요소 가져오기 → 콜백 함수 생성 → 리스너 등록

const button = document.querySelector('button')

// 이벤트 핸들러
const handleClick = function () {
  window.alert('버튼이 클릭 되었습니다!')
}

// addEventListener 메서드를 이용해 버튼에 이벤트 핸들러를 등록
button.addEventListener('click', handleClick)

이벤트 객체 전달

  • 이벤트 발생 시, 이벤트 객체는 자동으로 이벤트 핸들러 함수에 인자로 전달됨
  • 핸들러 함수는 이 인자를 통해 이벤트에 대한 상세 정보(이벤트 발생 요소, 이벤트 타입, 추가 데이터 등)에 접근할 수 있음
<button id="btn">버튼</button>
// 1. 버튼 요소 선택
const btn = document.querySelector('#btn')

// 2. 이벤트 핸들러
const detectClick = function (event) {
  console.log(event)      // PointerEvent
  console.log(event.type) // click
}

// 3. 버튼에 이벤트 핸들러를 등록
btn.addEventListener('click', detectClick)

이벤트 핸들러에서의 this

  • 일반 함수를 핸들러로 사용 시, this이벤트 리스너가 연결된 요소를 가리킴
  • event.currentTarget 속성 값과 동일
const btn = document.querySelector('#btn')

const detectClick = function (event) {
  console.log(event.currentTarget) // <button id="btn">버튼</button>
  console.log(this)                // <button id="btn">버튼</button>
}

btn.addEventListener('click', detectClick)

3. 버블링 (Bubbling)

form > div > p 형태의 중첩된 구조에 각각 이벤트 핸들러가 연결되어 있을 때, <p> 요소를 클릭해도 모든 부모 요소의 핸들러가 실행됨.

const formElement = document.querySelector('#form')
const divElement = document.querySelector('#div')
const pElement = document.querySelector('#p')

const clickHandler1 = function (event) {
  console.log('form이 클릭되었습니다.')
}
const clickHandler2 = function (event) {
  console.log('div가 클릭되었습니다.')
}
const clickHandler3 = function (event) {
  console.log('p가 클릭되었습니다.')
}

formElement.addEventListener('click', clickHandler1)
divElement.addEventListener('click', clickHandler2)
pElement.addEventListener('click', clickHandler3)

<p> 클릭 시 출력 결과:

p가 클릭되었습니다.
div가 클릭되었습니다.
form이 클릭되었습니다.

→ 사실 addEventListener를 3개 쓸 필요 없다. 어차피 버블링으로 최상단 조상(form)까지 가니까.
그럼 각각을 구분할 수 있는 방법은? → 이벤트가 정확히 어디서 발생했는지 접근하는 두 가지 속성을 사용한다.

1) event.currentTarget

  • 현재 요소 (= 이벤트 핸들러가 연결된 요소)
  • 항상 이벤트 핸들러가 연결된 요소만을 참조
  • this와 동일

2) event.target

  • 이벤트가 발생한 가장 안쪽의 요소(target) 를 참조

target & currentTarget 예시

<div id="outerouter">
  outerouter
  <div id="outer">
    outer
    <div id="inner">inner</div>
  </div>
</div>

<script>
  const outerOuterElement = document.querySelector('#outerouter')

  const clickHandler = function (event) {
    console.log('currentTarget:', event.currentTarget.id)
    console.log('target:', event.target.id)
  }

  outerOuterElement.addEventListener('click', clickHandler)
</script>

inner 클릭 시 결과:

currentTarget: outerouter
target: inner

inner를 클릭했을 때 등록된 event handler가 없으니까 아무 일도 안 일어나는 게 아니라,
버블링에 의해 계속 부모 요소로 이동하다가 outerouter를 만나서 등록된 event handler가 실행되는 것!


4. 캡처링 (Capturing)

  • 버블링과 반대 방향으로 이벤트가 전파됨 (최상위 조상 → target)

5. 버블링의 필요성

  • 요소들의 공통 조상에 이벤트 핸들러를 하나만 등록하면, 여러 자식 요소에서 발생하는 이벤트를 한 곳에서 효율적으로 다룰 수 있음
  • 공통 조상(div)에 할당한 핸들러에서 event.target을 이용하면 실제 어떤 자식 요소에서 이벤트가 발생했는지 알 수 있기 때문

6. lodash

  • 자바스크립트 유틸리티 라이브러리

7. 이벤트 기본 동작 취소하기 ⭐

HTML의 각 요소가 기본적으로 가지고 있는 이벤트가 때로는 방해되는 경우가 있어 취소할 필요가 있다.

preventDefault()

  • 해당 이벤트에 대한 기본 동작을 실행하지 않도록 지정
  • ex) 실수로 뒤로가기 눌렀을 때 "정말 이동하시겠습니까?"

실습 1) copy 이벤트 동작 취소 - 콘텐츠 복사 방지

// 복사 이벤트 금지
const h1Tag = document.querySelector('h1')

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

실습 2) form 제출 시 페이지 새로고침 동작 취소

  • form 제출 시 기본적으로 새로고침이 실행됨
  • submit 동작 취소를 통해 새로고침 방지
// 폼 제출 시 페이지 새로고침 동작 취소
const formTag = document.querySelector('#my-form')

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

formTag.addEventListener('submit', handleSubmit)

🔖 오늘의 정리

개념핵심
event웹 페이지에서 발생한 사건
addEventListenerDOM 요소에 이벤트 핸들러 등록
버블링자식 → 부모로 이벤트 전파
캡처링부모 → 자식으로 이벤트 전파
event.target실제 이벤트가 발생한 요소
event.currentTarget핸들러가 연결된 요소 (= this)
preventDefault()기본 동작 취소
profile
뭘봐

0개의 댓글