Daejlee 2024. 10. 3. 16:37

1. 이벤트 객체

이벤트 발생 시 이벤트 객체가 생성된다.

생성된 이벤트 객체는 이벤트 핸들러의 첫 번째 인수로 전달된다.

이는 브라우저가 이벤트 핸들러를 호출할 때 이벤트 객체를 인수로 전달하기 때문에, 전달받을 매개변수를 명시적으로 선언해야 하기 때문이다.

이벤트가 발생하면 암묵적으로 생성되는 이벤트 객체 또한 생성자 함수에 의해 생성된다.

이는 프로토타입 체인의 일원이 된다.

Event.prototype에 정의된 이벤트 프로퍼티는 모든 파생 객체에 상속된다.

더보기
공통 프로퍼티 설명 타입
type 이벤트 타입 string
target 이벤트를 발생시킨 DOM 요소 DOM 요소 노드
currentTarget 이벤트 핸들러가 바인딩된 DOM 요소 DOM 요소 노드
eventPhase 이벤트 전파 단계
0: 이벤트 없음, 1: 캡처링, 2: 타깃, 3: 버블링
number
bubbles 이벤트를 버블링으로 전파하는지 여부, 아래 이벤트는 bubbles: false로 버블링 하지 않는다.
포커스 이벤트: focus/blur
리소스 이벤트: load/unload/abort/error
마우스 이벤트: mouseenter/mouseleave
boolean
cancelable preventDefault 메서드로 이벤트의 기본 동작을 취소할 수 있는지 여부, 다음 이벤트는 cancelable: false로 취소 블가.
포커스 이벤트: focus/blur
리소스 이벤트: load/unload/abort/error
마우스 이벤트: dbclick/mouseenter/mouseleave
boolean
defaultPrevented preventDefault 메서드로 이벤트를 취소했는지 여부 boolean
isTrusted 사용자 행위로 발생한 이벤트인지 여부 boolean
timeStamp 이벤트가 발생 시각(1970/01/01/00:00:0부터 경과한 밀리초) number

 

2. 이벤트 전파

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

이를 이벤트 전파(Event propagation)라고 한다.

<ul id='fruits'>
	<li>apple</li>
	<li>banana</li>
	<li>orange</li>
</ul>

li 요소를 클릭하면 클릭 이벤트가 발생하고, 이때 생성된 이벤트 객체는 이벤트를 발생시킨 DOM 요소인 이벤트 타깃을 중심으로 DOM 트리를 통해 전파된다.

  • 캡처링 단계: 이벤트가 상위에서 하위 요소로 전파
  • 타깃 단계: 이벤트가 타깃에 도달
  • 버블링 단계: 이벤트가 하위 요소에서 상위 요소 방향으로 전파

이처럼 이벤트는 이벤트를 발생시킨 타깃은 물론 상위 DOM 요소에서도 캐치할 수 있다.

DOM 트리를 통해 전파되는 이벤트는 이벤트 경로(Event.prototype.composedPath)에 위치한 모든 DOM 요소에서 캐치 가능하다.

3. 이벤트 위임

이벤트 위임(event delegation)은 여러 하위 DOM 요소에 개별적으로 이벤트 핸들러를 등록하지 않고, 하나의 상위 DOM 요소에 등록하는 방법이다.

다만 주의할 점은 이벤트를 일으킨 타겟이 개발자가 기대한 DOM 요소가 아닐 수 있다는 것이다.

이것을 고려해서 이벤트 타겟을 검사할 필요가 있다.

4. DOM 요소의 기본 동작 조작

이벤트 객체의 preventDefault 메서드는 이러한 DOM 요소의 기본 동작을 중단시킨다.

document.querySelector('a').onclick = e => {
	e.preventDefault(); // a 태그의 기본 동작 중단
};
document.querySelector('input[type=checkbox]').onclick = e => {
	e.preventDefault();	// checkbox의 기본 동작 중단
};

이벤트 객체의 stopPropagation 메서드는 이벤트 전파를 중지시킨다.

<div class="container">
	<button class="btn1">Button 1</button>
	<button class="btn2">Button 2</button>
	<button class="btn3">Button 3</button>
</div>
<script>
	// 이벤트 위임, 클릭된 하위 버튼 요소의 color를 변경한다.
	document.querySelector('.container').onclick = ({ target }) => {
		if (!target.matches('.container > button')) return;
		target.style.color = 'red';
	};
	// .btn2 요소는 이벤트를 전파하지 않는다. 상위 요소에서 이벤트 캐치가 불가능하다.
	document.querySelector('.btn2').onclick = e => {
		e.stopPropagation();
		e.target.style.color = 'blue';
	};
</script>