40. 이벤트

2025. 1. 6. 16:47기록/Modern JavaScript Deep Dive

이벤트 드리븐 프로그래밍

이벤트 핸들러

  • 이벤트가 발생했을 때 호출될 함수

 

이벤트 핸들러 등록

  • 이벤트가 발생했을 때 브라우저에게 이벤트 핸들러의 호출을 위임하는 것

 

이벤트 드리븐 프로그래밍

  • 이벤트와 그에 대응하는 함수(이벤트 핸들러)를 통해 사용자와 애플리케이션은 상호작용을 할 수 있음
  • 프로그램의 흐름을 이벤트 중심으로 제어하는 프로그래밍 방식

이벤트 타입

마우스 이벤트

이벤트 타입 이벤트 발생 시점
click 마우스 버튼을 클릭했을 때
dbclick 마우스 버튼을 더블 클릭했을 때
mousedown 마우스 버튼을 눌렀을 때
mouseup 누르고 있던 마우스 버튼을 놓았을 때
mousemove 마우스 커서를 움직였을 때
mouseenter 마우스 커서를 HTML 요소 안으로 이동했을 때 (버블링 X)
mouseover 마우스 커서를 HTML 요소 안으로 이동했을 때 (버블링 O)
mouseleave 마우스 커서를 HTML 요소 밖으로 이동했을 때 (버블링 X)
mouseout 마우스 커서를 HTML 요소 밖으로 이동했을 때 (버블링 O)

 

키보드 이벤트

keydown 모든 키를 눌렀을 때
keypress 문자 키를 눌렀을 때 연속적으로 발생
(deorecated 되었으므로 사용하지 않을 것을 권장함)
keyup 누르고 있던 키를 놓았을 때 한 번만 발생

 

포커스 이벤트

focus HTML 요소가 포커스를 받았을 때 (버블링 X)
blur HTML 요소가 포커스를 잃었을 때 (버블링 X)
focusin HTML 요소가 포커스를 받았을 때 (버블링 O) / addEventListener 메서드 방식을 사용해야함
focusout HTML 요소가 포커스를 잃었을 때 (버블링 O) / addEventListener 메서드 방식을 사용해야함

 

폼 이벤트

submit 1. form 요소 내의 input(text, checkbox, radio), select 입력 필드(textarea 제외)에서 엔터키를 눌렀을 때
2. form 요소 내의 submit 버튼을 클릭했을 때

 

값 변경 이벤트

input input, select, textarea 요소의 값이 입력되었을 때
사용자가 입력을 하고 있을 때 발생
change input, select, textarea 요소의 값이 입력되었을 때
사용자 입력이 종료되어 값이 변경될 때 발생 (해당 요소가 포커스를 잃었을 때)
readystatechange HTML 문서의 로드/파싱 상태를 나타내는 document.readyState 프로퍼티 값
('loading', 'interactive', 'complete')이 변경될 때

 

DOM 뮤테이션 이벤트

DOMContentLoaded HTML 문서의 로드/파싱이 완료되어 DOM 생성이 완료되었을 때

 

뷰 이벤트

resize 브라우저 윈도우의 크기를 리사이즈할 때 연속적으로 발생
scroll 웹페이지 또는 HTML 요소를 스크롤할 때 연속적으로 발생

 

리소스 이벤트

load DOMContentLoaded 이벤트 발생 후, 모든 리소스의 로딩이 완료되었을 때 (주로 window 객체에서 발생)
unload 리소스가 언로드될 때 (주로 새로운 웹페이지 요청 시)
abort 리소스 로딩이 중단되었을 때
error 리소스 로딩이 실패했을 때

이벤트 핸들러 등록

1. 이벤트 핸들러 어트리뷰트 방식

<button onclick="sayHi('Lee')">Click Me!</button>
...
function sayHi(name) {
  console.log(`Hi! ${name}!`);
}
  • on 접두사 사용
  • 함수 참조를 등록해야 브라우저가 이벤트 핸들러 호출 가능
  • 함수 호출문을 등록하면 함수 호출문의 평과 결과가 이벤트 핸들러로 등록됨

 

2. 이벤트 핸들러 프로퍼티 방식

buttonEl.onclick = function () {
  console.log('click!');
};
  • 이벤트 타깃.on+이벤트타입 = 이벤트핸들러
    • 이벤트 타깃: 이벤트를 발생시킬 객체
    • 이벤트 타입: 이벤트의 종류를 나타내는 문자열
    • 이벤트 핸들러: 함수
  • 이벤트 핸들러 프로퍼티에 하나의 이벤트 핸들러만 바인딩 가능

 

3. addEventListener 메서드 방식

EventTarget.addEventListener('eventType', functionName [, useCapture]);
  • 첫 번째 매개변수: 이벤트의 종류를 나타내는 문자열인 이벤트 타입 전달 (on 접두사 X)
  • 두 번째 매개변수: 이벤트 핸들러 전달
  • 마지막 매개변수: 이벤트를 캐치할 이벤트 전파 단계 지정
    • 생략/false 시 버블링 단계에서 이벤트 캐치
    • true 시 캡쳐링 단계에서 이벤트 캐치
  • 하나 이상의 이벤트 핸들러 등록 가능 (등록 순서대로 호출됨)

이벤트 핸들러 제거

addEventListener 메서드로 등록한 이벤트 핸들러 제거

  • removeEventListener 메서드 사용
  • addEventListener 메서드에 전달한 인수와 removeEventListener 메서드에 전달한 인수가 일치해야 제거됨

 

이벤트 핸들러 프로퍼티 방식으로 등록한 이벤트 핸들러 제거

  • 이벤트 핸들러 프로퍼티에 null 할당

이벤트 객체

function handleClick (event) {
  console.log(event);
}
  • 이벤트 발생 시 이벤트 객체가 동적으로 생성되고 이벤트 핸들러의 첫 번째 인수로 전달됨
  • 이벤트 핸들러 어트리뷰트 방식일 경우
    • 이벤트 핸들러의 첫 번째 매개변수 이름이 event 이어야 이벤트 객체를 전달받을 수 있음

 

이벤트 객체의 공통 프로퍼티

공통 프로퍼티 설명 타입
type 이벤트 타입 string
target 이벤트를 발생시킨 DOM 요소 DOM 요소 노드
currentTarget 이벤트 핸들러가 바인딩된 DOM 요소 DOM 요소 노드
eventPhase 이벤트 전파 단계
0: 이벤트 없음
1: 캡쳐링 단계
2. 타깃 단계
3. 버블링 단계
number
bubbles 이벤트를 버블링으로 전파하는지 여부

버블링 불가능한 이벤트
focus / blur / load / unload / abort
error / mouseenter / mouseleave
boolean
cancelable preventDefault 메서드를 호출하여
이벤트의 기본 동작을 취소할 수 있는지 여부

취소 불가능한 이벤트
focus / blur / load / unload / abort
error / dbclick / mouseenter / mouseleave
boolean
defaultPrevented preventDefault 메서드를 호출하여 이벤트를 취소했는지 여부 boolean
isTrusted 사용자의 행위에 의해 발생한 이벤트인지 여부
(click 메서드 / dispatchEvent 메서드를 통해 인위적으로 발생시킨 이벤트일 경우 false)
boolean
timeStamp 이벤트가 발생한 시각 (1970/01/01/00:00:0 부터 경과한 밀리초) number

 

마우스 정보 취득

마우스 이벤트가 발생하면 생성되는 MouseEvent 타입의 이벤트 객체는

아래와 같은 고유의 프로퍼티를 가짐

 

마우스 포인터의 좌표 정보를 나타내는 프로퍼티

  • screenX/screenY, clientX/clientY, pageX/pageY, offsetX/offsetY

 

버튼 정보를 나타내는 프로퍼티

  • altKey, ctrlKey, shiftKey, button

 

키보드 정보 취득

키보드 이벤트가 발생하면 생성되는 keyboardEvent 타입의 이벤트 객체는

altKey, ctrlKey, shiftKey, metaKey, key, keyCode(폐지) 같은 고유의 프로퍼티를 가짐


이벤트 전파

DOM 트리 상에 존재하는 DOM 요소 노드에서 발생한 이벤트가 DOM 트리를 통해 전파되는 것

이벤트 객체가 전파되는 방향에 따라 3단계로 구분 가능

 

캡쳐링 단계

  • 이벤트가 상위요소에서 하위 요소 방향으로 전파
  • window -> document -> html -> body -> ul -> li

 

타깃 단계

  • 이벤트가 이벤트 타깃에 도달
  • li

 

버블링 단계

  • 이벤트가 하위 요소에서 상위 요소 방향으로 전파
  • li -> ul -> body -> html -> document -> window

 

이벤트 핸들러 어트리뷰트/프로퍼티 방식으로 등록한 이벤트 핸들러

  • 타깃 단계, 버블링 단계의 이벤트만 캐치 가능

 

addEventListener 메서드 방식으로 등록한 이벤트 핸들러

  • 타깃 단계, 버블링 단계, 캡쳐링 단계 이벤트 모두 캐치 가능

이벤트 위임

여러 개의 하위 DOM 요소에 각각 이벤트 핸들러를 등록하는 대신

하나의 상위 DOM 요소에 이벤트 핸들러를 등록하는 방법

이벤트에 반응이 필요한 DOM 요소에 한정하여 이벤트 핸들러가 실행되도록 이벤트 타깃을 검사해야 함


DOM 요소의 기본 동작 조작

  • DOM 요소는 기본 동작을 가지고 있음 (a태그 클릭 시 href 어트리뷰트에 지정된링크로 이동 등)
  • 이벤트 객체의 preventDefault 메서드는 DOM 요소의 기본 동작을 중단시킴
  • 이벤트 객체의 stopPropagation 메서드는 이벤트 전파를 중지시킴

이벤트 핸들러 내부의 this

이벤트 핸들러 어트리뷰트 방식

<button onclick="handleClick()">Click Me</button>
...
function handleClick() {
  console.log(this); // window
}
  • 일반 함수로 호출되는 함수 내부의 this 는 전역 객체를 가리킴 (window)

 

<button onclick="handleClick(this)">Click Me</button>
...
function handleClick(button) {
  console.log(button); // 이벤트를 바인딩한 button 요소
  console.log(this); // window
}
  • 이벤트 핸들러를 호출할 때 인수로 전달한 this 는 이벤트를 바인딩한 DOM 요소를 가리킴

 

이벤트 핸들러 프로퍼티 방식 / addEventListener 메서드 방식

  • 이벤트 핸들러 내부의 this 는 이벤트를 바인딩한 DOM 요소를 가리킴 (=== 이벤트 객체의 currentTarget)
  • 화살표 함수로 정의한 이벤트 핸들러 내부의 this 는 상위 스코프의 this 를 가리킴