DOM - 이벤트

JavaScript Front-end

DOM 이벤트

이벤트(Event)는 어떤 일 또는 인터랙션이 발생했을 때, 그 시점에 발생하는 신호를 말한다. DOM에서는 요소를 클릭하거나, 특정 키를 입력했을 때 등 다양한 상황에서 이벤트가 발생한다.

target, currentTarget

이벤트가 발생한 요소에 접근하고 싶은 경우, target 또는 currentTarget 프로펕를 통해 접근할 수 있다.

  • target : 이벤트가 처음 발생했던 대상 DOM의 요소를 참조를 갖는다.
  • currentTarget : 발생한 이벤트가 등록된 DOM 요소의 참조를 갖는다.

preventDefault(), stopPropagation()

이벤트 제어 메서드이다.

  • preventDefault()는 이벤트를 취소할 수 있는 경우 이벤트를 취소한다. 대신 전파(캡쳐링, 버블링)되는 이벤트를 막지 않으며, 현재 이벤트의 기본 동작만 중단한다.
  • stopPropagation()preventDefault()처럼 기본 동작을 중단하지는 못하지만 이벤트가 전파되는 것을 막는다.

이벤트 종류

UI 이벤트

이름 설명
load 문서나 종속된 리소스(이미지나 스크립트 파일, CSS 파일 등)가 완전히 로드되었을 때 발생한다.
unload 문서나 종속된 리소스가 완전히 제거되었을 때 발생한다.
abort 리소스가 중단된 경우(로드가 진행되는 동안 사용자가 취소한 경우 등) 발생한다.
error 리소스가 로드되었지만 유효하지 않을 때, 스크립트 실행 오류, 잘못된 형식 등의 에러가 발생했을 때 발생한다.
select <input>, <textarea> 요소 안에 작성된 텍스트를 선택할 경우 발생한다.

Focus 이벤트

이름 설명
focusin 포커스를 받으려 할 때 발생한다. target은 이벤트를 받을 요소이다.
focusout 포커스를 잃으려 할 때 발생한다. target은 이벤트를 잃게 될 요소이다.
focus focusin과 비슷하지만 포커스를 받은 뒤 발생한다.
blur focusout과 비슷하지만 포커스를 잃은 뒤 발생한다.

마우스 이벤트

*마우스 이벤트는 항상 가장 깊이 중첩된 요소를 대상으로 한다.

이름 설명
mousedown 타깃을 눌렀을 때 발생한다.
mouseup 타깃의 위에서 눌렀던 포인트가 해제될 때 발생한다.
click 타깃에 클릭을 했을 때 발생한다. mousedown, mouseup 이벤트가 둘 다 발생한 후 발생한다.
dblclick 더블 클릭을 했을 경우 발생한다.
mousemove 타깃 내에서 포인터가 이동할 경우 발생한다.
mouseenter 타깃 밖에서 타깃 안으로 처음 포인터가 이동할 때 발생한다.
mouseleave 타깃 밖으로 이동할 때 발생한다.
mouseover mouseenter와 동일한 조건에서 발생한다. 다른 점은 이벤트가 버블링된다.
mouseout mouseout과 동일한 조건에서 발생한다. 다른 점은 이벤트가 버블링된다.

Input 이벤트

이름 설명
beforeinput 입력 후 DOM 요소에 업데이트 되기 전 발생한다.
input 입력 후 DOM 요소에 업데이트 된 후 바로 발생한다.

키보드 이벤트

이름 설명
keydown 키보드를 누른 순간 발생한다.
keyup 누른 키를 뗄 때 발생한다.

이벤트 리스너 추가하기

이벤트 리스너를 추가하는 방법은 크게 세 가지가 있다.

  1. DOM 프로퍼티로 할당하는 방법
  2. HTML 요소에 속성으로 할당하는 방법
  3. (권장) addEventListener()

addEventListener()

한 이벤트 타입에 여러 개의 리스너를 등록할 수 있으며 버블링을 사용할지, 캡쳐링을 사용할지 등 정밀한 제어를 할 수 있다.

<button id='my-button'> Click me! </button>

<script>
  document.getElementById('my-button').addEventListener('click', (event) => {
    alert('You clicked me!');
  }, true); // 캡쳐링 사용
</script>

Event Propagation (버블링, 캡쳐링)

계층적 구조를 가진 DOM에 이벤트가 발생할 경우 연쇄적으로 이벤트가 전파된다. 이벤트가 전파되는 방향에 따라 버블링(Bubbling)과 캡쳐링(Capturing)으로 구분된다.

버블링(Bubbling)

DOM 요소에 이벤트가 발생할 경우 부모 요소로 올라가며 차례대로 이벤트가 전파되는 흐름을 뜻한다. 대부분의 이벤트는 버블링을 기본 동작으로 갖는다.

<form id='my-form'>
  <div id='my-div'>
    <p id='my-p'>
    </p>
  </div>
</form>

<script>
  const form = document.getElementById('my-form');
  const div = document.getElementById('my-div');
  const p = document.getElementById('my-p');

  [form, div, p].forEach(target => {
    target.addEventListener('click', () => {
      console.log(`${String(target.tagName)} 클릭`);
    });
  });
  
</script>

<p> 영역을 클릭할 경우 등록된 이벤트 리스너가 실행되며, 부모 요소에 등록된 클릭 이벤트 리스너가 차례대로 실행된다.

“P 클릭”, “DIV 클릭”, “FORM 클릭”

bubbling

캡쳐링(Capturing)

버블링과 반대로 가장 상위의 부모 요소에서 자식 요소로 내려가며 이벤트가 전파되는 것을 캡쳐링이라고 한다. addEventListener()의 세 번째 옵션을 통해 이벤트 리스너를 캡쳐링 단계에서 실행시킬 수 있다.

<script>
  const form = document.getElementById('my-form');
  const div = document.getElementById('my-div');
  const p = document.getElementById('my-p');

  [form, div, p].forEach(target => {
    target.addEventListener('click', () => {
      console.log(`${String(target.tagName)} 클릭`);
    }, true);
  });
  
</script>

“FORM 클릭”, “DIV 클릭”, “P 클릭”

capturing

표준 DOM의 이벤트는 캡쳐링, 타깃, 버블링의 흐름 순서를 가진다.


출처
기초부터 완성까지, 프런트엔드(이재성)