[HOW]웹 프로그램에서 이벤트 관리

HOW

 ⋅ Feb 6, 2024 ⋅ 3 min read

Firecracker
Firecracker

브라우저는 특정 사건 발생 시 이벤트를 발생시킵니다. 이때 이벤트에 반응하여 특정 작업을 수행하고 싶다면 해당 타입의 이벤트가 발생했을 때 호출될 함수를 브라우저에 알려 호출을 위임합니다. 이벤트가 발생했을 때 호출될 함수를 이벤트 핸들러라 하며, 이벤트가 발생했을 때 브라우저에 이벤트 핸들러의 호출을 위임하는 것을 이벤트 핸들러 등록이라 합니다.

이처럼 이벤트 중심으로 프로그램의 흐름을 관리하는 프로그래밍 방식을 이벤트 드리븐 프로그래밍이라 합니다.

1. 이벤트 핸들러 등록

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

    HTML 요소의 어트리뷰트 중에 이벤트에 대응하는 이벤트 핸들러 어트리뷰트가 존재합니다. 이벤트 핸들러 어트리뷰트의 이름은 on 접두사와 이벤트 종류를 나타내는 이벤트 타입으로 이루어져 있으며 함수 호출문 등의 문을 할당하면 이벤트 핸들러가 등록됩니다. 함수 호출문 형식 같은 형태로 할당하는 이유는 이벤트 핸들러에 인수를 전달하기 위해서입니다. 이벤트 핸들러 어트리뷰트 값은 사실 암묵적으로 생성될 이벤트 핸들러의 함수 몸체를 의미합니다.

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

    window 객체와 Document, HTMLElement 타입의 DOM 노드 객체는 이벤트에 대응하는 이벤트 핸들러 프로퍼티를 가지고 있습니다. 이벤트 핸들러 프로퍼티의 키는 이벤트 핸들러 어트리뷰트와 마찬가지로 on 접두사와 이벤트 종류를 나타내는 이벤트 타입으로 구성되어 있습니다. 이벤트 핸들러 등록을 위해 이벤트를 발생시킬 객체인 이벤트 타깃과 이벤트의 종류를 나타내는 이벤트 타입, 이벤트 핸들러를 지정할 필요가 있습니다. 이벤트 핸들러는 이벤트 타깃 또는 전파된 이벤트를 캐치할 DOM 노드 객체에 바인딩합니다.

  3. addEventListener 메서드 방식

    EventTarget.addEventListener 메서드를 통해 이벤트 핸들러 등록이 가능합니다. 첫 번째 매개변수로 이벤트 타입을 전달하며, 두 번째 매개변수에는 이벤트 핸들러를 전달합니다. 마지막 매개변수에는 이벤트를 캐치할 이벤트 전파 단계(캡처링 또는 버블링)를 전달하며 false를 전달하면 버블링 단계에서 이벤트 캐치하며, true를 전달하면 캡처링 단계에서 이벤트 캐치합니다.

    동일한 HTML 요소에서 발생한 동일한 이벤트에 대해 이벤트 핸들러 프로퍼티 방식은 하나 이상의 이벤트 핸들러를 등록할 수 없지만 addEventListener 메서드는 하나 이상의 이벤트 핸들러를 등록할 수 있습니다. 이벤트 핸들러는 등록된 순서대로 동작합니다.

2. 이벤트 핸들러 제거

EventTarget.removeEventListener 메서드를 통해 이벤트 핸들러 제거가 가능합니다. addEventListener와 동일한 매개 변수를 가지며 동일한 인수를 전달하여 이벤트 핸들러를 제거합니다.

이벤트 핸들러 프로퍼티 방식으로 등록한 이벤트 핸들러는 EventTarget.removeEventListener 메서드로 제거할 수 없으며 이 경우에는 null을 할당하여 제거할 수 있습니다.

3. 이벤트 객체

웹 페이지의 이벤트 발생 시 동적으로 이벤트 객체가 생성됩니다. 이벤트 객체는 이벤트에 관한 여러 정보를 포함하고 있으며, 이벤트 핸들러의 첫 번째 인수로 전달됩니다.

4. 이벤트 전파

이벤트 전파는 DOM 트리 상에 존재하는 요소 노드에서 발생한 이벤트가 DOM 트리를 통해 전달되는 것을 의미합니다.

예를 들어 클릭 이벤트가 발생한 경우 생성된 이벤트 객체는 이벤트를 발생시킨 DOM 요소인 이벤트 타깃을 중심으로 DOM 트리를 통해 전파됩니다. 이벤트 전파 단계는 방향에 따라 3가지로 구분됩니다.

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

클릭 이벤트가 발생하면 클릭 이벤트 객체가 생성되고 클릭 된 요소가 이벤트 타깃이 됩니다. 이벤트 객체는 이후 window에서 시작하여 이벤트 타깃 방향으로 전파되며, 이를 캡처링 단계라고 합니다. 이벤트 객체는 이벤트 타깃에 도달하며, 이는 타깃 단계입니다. 타깃에 도달한 이벤트 객체는 다시 window 방향으로 전파되며, 이를 버블링 단계라고 합니다.

이벤트 타깃은 DOM 트리를 통해 전파되는 경로에 위치하는 모든 DOM 요소에서 캐치할 수 있습니다.

5. 이벤트 위임

여러 개의 DOM 요소에 동일한 이벤트 핸들러를 등록해야 하는 경우가 있습니다. 요소 개수가 많아지는 경우 성능 저하의 원인이 되며, 유지보수 측면에서도 부적절합니다.

이벤트 위임은 여러 개의 DOM 요소에 이벤트 핸들러를 등록하는 대신 요소들의 상위 요소에 이벤트 핸들러를 등록하는 방법입니다.

이벤트 위임을 활용하는 경우 주의해야 할 점은 이벤트를 발생한 요소가 생각과 다른 DOM 요소일 수도 있다는 점입니다. 따라서, 이벤트 핸들러가 실행되기 위해 이벤트 타깃을 검사해야 할 필요가 있습니다.

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

DOM 요소의 기본 동작 중단

DOM 요소는 기본 동작을 가지고 있습니다. 이벤트 객체의 preventDefault 메서드는 DOM 요소의 기본 동작을 중단시키는 역할을 합니다.

이벤트 전파 방지

이벤트 객체의 stopPropagation 메서드는 이벤트 전파를 중지시키는 역할을 수행합니다. 하위 요소에서 발생한 이벤트를 상위 요소로 전파되는 것을 막아 하위 요소의 이벤트를 개별적으로 처리하도록 합니다.

7. 이벤트 핸들러에 인수 전달

이벤트 핸들러 어트리뷰트 방식은 함수 호출문을 사용 가능하기 때문에 인수 전달이 가능하지만, 이벤트 핸들러 프로퍼티 방식과 addEventListener 메서드 방식은 브라우저가 호출하기 때문에 함수 자체를 등록하여 인수 전달을 부가합니다.

하지만, 이벤트 핸들러 내부에서 함수를 호출하는 방법을 통해 인수 전달을 수행할 수 있습니다. 또한, 이벤트 핸들러를 반환하는 함수를 호출하면서 인수를 전달하는 방법도 존재합니다.

8. 커스텀 이벤트

커스텀 이벤트 생성

이벤트 생성자 함수를 통해 커스텀 이벤트를 생성할 수 있습니다. 이벤트 생성자 함수를 호출하여 명시적으로 생성한 이벤트 객체는 임의의 이벤트 타입을 지정할 수 있습니다.

이벤트 생성자 함수는 첫 번째 인수로 이벤트 타입을 전달받습니다. 또한 bubbles와 cancelable 프로퍼티를 true로 설정하려면 두 번째 인수로 bubbles와 cancelable 프로퍼티를 갖는 객체를 전달받습니다. 더불어 이벤트 타입에 따라 가지는 이벤트 고유의 프로퍼티 값 지정을 위해 두 번째 인수로 프로퍼티를 전달할 수 있습니다.

커스텀 이벤트 디스패치

dispatchEvent 메서드를 이용해 커스텀 이벤트를 발생시키는 디스패치를 할 수 있습니다. dispatchEvent 메서드에 이벤트 객체를 인수로 전달하면서 호출하면 인수로 전달한 이벤트 타입의 이벤트가 발생합니다.

dispatchEvent 메서드는 이벤트 핸들러를 동기 처리 방식으로 호출합니다. 따라서, 이벤트를 디스패치 하기 전에 커스텀 이벤트를 처리할 이벤트 핸들러를 등록해야 합니다. 커스텀 이벤트는 이벤트 핸들러 어트리뷰트와 프로퍼티가 요소 노드에 존재하지 않기 때문에 addEventListener 메서드 방식으로 이벤트 핸들러를 등록해야 한다.


참고

이웅모, ⌈모던 자바스크립트 - Deep Dive⌋, 2020, 40_이벤트(p.754 - 799)

이미지 출처 - https://pixabay.com/ko/photos/검은-색-터지다-축하하다-17121/

LINKS

© Copyright 2021

made by React.js & gatsby