Document Object Model (DOM)/Working with events

김동현·2026년 4월 7일

저번 문서에 이어서 이벤트(Event)와 관련된 MDN 문서를 번역해 드릴게요!

이번에도 원본의 구조를 그대로 유지하면서, 이해하기 쉬운 편안한 실무 구어체로 모든 내용을 빠짐없이 번역했습니다. 테이블 내의 링크와 예제 코드들도 모두 깔끔하게 마크다운으로 정리해 두었으니 천천히 읽어보세요.


이벤트 인덱스 (Event index)

이벤트 타입 (Event type)설명 (Description)관련 문서 (Documentation)
Animation (애니메이션)Web Animation API와 관련된 이벤트입니다.

애니메이션의 상태 변화(예: 애니메이션이 시작되거나 끝날 때)에 대응하기 위해 사용됩니다.
Document, Window, HTMLElement에서](https://developer.mozilla.org/en-US/docs/Web/API/HTMLElement#animation_events)에서) 발생하는 애니메이션 이벤트입니다.
Asynchronous data fetching (비동기 데이터 페칭)데이터를 가져오는 것과 관련된 이벤트입니다.AbortSignal, XMLHttpRequest, FileReader에서](https://developer.mozilla.org/en-US/docs/Web/API/FileReader#events)에서) 발생하는 이벤트입니다.
Clipboard (클립보드)Clipboard API와 관련된 이벤트입니다.

콘텐츠를 잘라내거나, 복사하거나, 붙여넣을 때 알림을 받기 위해 사용됩니다.
Document, Element, Window에서](https://developer.mozilla.org/en-US/docs/Web/API/Window#clipboard_events)에서) 발생하는 이벤트입니다.
Composition (조합)조합(Composition)과 관련된 이벤트로, 일반적인 키보드 누름이 아닌 "간접적으로" 텍스트를 입력할 때 발생합니다.

예를 들어, 음성 인식 엔진을 통해 텍스트를 입력하거나, 다른 언어의 문자를 표현하기 위해 키보드 입력을 변형시키는 특수 키 조합을 사용할 때 발생합니다.
Element에서](https://developer.mozilla.org/en-US/docs/Web/API/Element#composition_events)에서) 발생하는 이벤트입니다.
CSS transition (CSS 트랜지션)CSS Transitions와 관련된 이벤트입니다.

CSS 트랜지션이 시작, 정지, 취소될 때 등의 알림 이벤트를 제공합니다.
Document, HTMLElement, Window에서](https://developer.mozilla.org/en-US/docs/Web/API/Window#transition_events)에서) 발생하는 이벤트입니다.
Database (데이터베이스)데이터베이스 작업(열기, 닫기, 트랜잭션, 에러 등)과 관련된 이벤트입니다.IDBDatabase, IDBOpenDBRequest, IDBRequest, IDBTransaction에서](https://developer.mozilla.org/en-US/docs/Web/API/IDBTransaction#events)에서) 발생하는 이벤트입니다.
DOM mutation (DOM 변경)문서 객체 모델(DOM) 계층 구조 및 노드의 수정과 관련된 이벤트입니다.> 경고 (Warning):
> Mutation Events는 더 이상 권장되지 않습니다(deprecated). 대신 Mutation Observers를 사용해야 합니다.
Drag'n'drop, Wheel (드래그 앤 드롭, 휠)HTML Drag and Drop API휠(wheel) 이벤트 사용에 관련된 이벤트입니다.

드래그와 휠 이벤트는 마우스 이벤트에서 파생됩니다. 마우스 휠이나 드래그/드롭을 사용할 때 발생하지만, 적절한 다른 하드웨어 장치를 통해서도 발생할 수 있습니다.
Document에서](https://developer.mozilla.org/en-US/docs/Web/API/Document#drag_drop_events)에서) 발생하는 드래그 이벤트.

Element에서](https://developer.mozilla.org/en-US/docs/Web/API/Element/wheel_event)에서) 발생하는 휠 이벤트.
Focus (포커스)요소가 포커스를 얻거나 잃는 것과 관련된 이벤트입니다.Element, Window에서](https://developer.mozilla.org/en-US/docs/Web/API/Window#focus_events)에서) 발생하는 이벤트입니다.
Form (폼)폼이 구성되거나, 초기화(reset)되거나 제출(submit)되는 것과 관련된 이벤트입니다.HTMLFormElement에서](https://developer.mozilla.org/en-US/docs/Web/API/HTMLFormElement#events)에서) 발생하는 이벤트입니다.
Fullscreen (전체화면)Fullscreen API와 관련된 이벤트입니다.

전체 화면 모드와 창 모드 사이를 전환할 때, 그리고 이 전환 과정에서 에러가 발생했을 때 알림을 주기 위해 사용됩니다.
Document, Element에서](https://developer.mozilla.org/en-US/docs/Web/API/Element#fullscreen_events)에서) 발생하는 이벤트입니다.
Gamepad (게임패드)Gamepad API와 관련된 이벤트입니다.Window에서](https://developer.mozilla.org/en-US/docs/Web/API/Window#gamepad_events)에서) 발생하는 이벤트입니다.
Gestures (제스처)제스처를 구현할 때는 터치 이벤트(Touch events)를 사용하는 것을 권장합니다.Document, Element에서](https://developer.mozilla.org/en-US/docs/Web/API/Element#touch_events)에서) 발생하는 이벤트입니다.

추가로 다음과 같은 비표준 제스처 이벤트들도 있습니다:
History (히스토리)History API와 관련된 이벤트입니다.Window에서](https://developer.mozilla.org/en-US/docs/Web/API/Window#history_events)에서) 발생하는 이벤트입니다.
HTML element content display management (HTML 요소 콘텐츠 디스플레이 관리)디스플레이 요소나 텍스트 요소의 상태 변경과 관련된 이벤트입니다.HTMLDetailsElement, HTMLDialogElement, HTMLSlotElement에서](https://developer.mozilla.org/en-US/docs/Web/API/HTMLSlotElement#events)에서) 발생하는 이벤트입니다.
Inputs (입력)<input>, <select>, <textarea>와](https://developer.mozilla.org/en-US/docs/Web/HTML/Reference/Elements/textarea)와) 같은 HTML 입력 요소와 관련된 이벤트입니다.HTMLElement, HTMLInputElement에서](https://developer.mozilla.org/en-US/docs/Web/API/HTMLInputElement#events)에서) 발생하는 이벤트입니다.
Keyboard (키보드)키보드 사용에 관련된 이벤트입니다.

키가 올라가거나, 내려가거나, 방금 눌렸을 때 알림을 주기 위해 사용됩니다.
Document, Element에서](https://developer.mozilla.org/en-US/docs/Web/API/Element#keyboard_events)에서) 발생하는 이벤트입니다.
Loading/unloading documents (문서 로딩/언로딩)문서를 불러오고(loading) 내리는(unloading) 것과 관련된 이벤트입니다.DocumentWindow에서](https://developer.mozilla.org/en-US/docs/Web/API/Window#load_unload_events)에서) 발생하는 이벤트입니다.
Manifests (매니페스트)프로그레시브 웹 앱 매니페스트(PWA manifests)의 설치와 관련된 이벤트입니다.Window에서](https://developer.mozilla.org/en-US/docs/Web/API/Window#manifest_events)에서) 발생하는 이벤트입니다.
Media (미디어)미디어 사용과 관련된 이벤트입니다 (Media Capture and Streams API, Web Audio API, Picture-in-Picture API 등 포함).ScriptProcessorNode, HTMLMediaElement, AudioTrackList, AudioScheduledSourceNode, MediaRecorder, MediaStream, MediaStreamTrack, VideoTrackList, HTMLTrackElement, OfflineAudioContext, TextTrack, TextTrackList, Element/audio, Element/video에서 발생하는 이벤트입니다.
Messaging (메시징)한 창(Window)이 다른 브라우징 컨텍스트로부터 메시지를 받는 것과 관련된 이벤트입니다.Window에서](https://developer.mozilla.org/en-US/docs/Web/API/Window#messaging_events)에서) 발생하는 이벤트입니다.
Mouse (마우스)컴퓨터 마우스 사용에 관련된 이벤트입니다.

마우스 클릭, 더블 클릭, 마우스 버튼을 누르고 떼는 이벤트, 우클릭, 요소 안팎으로의 이동, 텍스트 선택 등을 알리기 위해 사용됩니다.

포인터(Pointer) 이벤트는 마우스 이벤트를 대체할 수 있는 하드웨어 독립적인 대안을 제공합니다. 드래그와 휠 이벤트는 마우스 이벤트에서 파생됩니다.
Element에서](https://developer.mozilla.org/en-US/docs/Web/API/Element#mouse_events)에서) 발생하는 마우스 이벤트입니다.
Network/Connection (네트워크/연결)네트워크 연결을 얻거나 끊기는 것과 관련된 이벤트입니다.Window에서](https://developer.mozilla.org/en-US/docs/Web/API/Window#connection_events)에서) 발생하는 이벤트입니다.

NetworkInformation에서](https://developer.mozilla.org/en-US/docs/Web/API/NetworkInformation#event_handler)에서) 발생하는 이벤트입니다 (Network Information API).
Payments (결제)Payment Request API와 관련된 이벤트입니다.PaymentRequest, PaymentResponse에서](https://developer.mozilla.org/en-US/docs/Web/API/PaymentResponse#events)에서) 발생하는 이벤트입니다.
Performance (성능)Performance APIs로 그룹화된 모든 성능 관련 명세의 이벤트입니다.Performance에서](https://developer.mozilla.org/en-US/docs/Web/API/Performance#events)에서) 발생하는 이벤트입니다.
Pointer (포인터)Pointer Events API와 관련된 이벤트입니다.

마우스, 터치, 펜/스타일러스를 포함한 포인팅 장치로부터 하드웨어에 구애받지 않는 알림을 제공합니다.
Document, HTMLElement에서](https://developer.mozilla.org/en-US/docs/Web/API/HTMLElement#pointer_events)에서) 발생하는 이벤트입니다.
Print (인쇄)인쇄와 관련된 이벤트입니다.Window에서](https://developer.mozilla.org/en-US/docs/Web/API/Window#print_events)에서) 발생하는 이벤트입니다.
Promise rejection (프로미스 거부)자바스크립트 프로미스(Promise)가 거부(rejected)될 때 전역 스크립트 컨텍스트로 전송되는 이벤트입니다.Window에서](https://developer.mozilla.org/en-US/docs/Web/API/Window#promise_rejection_events)에서) 발생하는 이벤트입니다.
Sockets (소켓)WebSockets API와 관련된 이벤트입니다.WebSocket에서](https://developer.mozilla.org/en-US/docs/Web/API/WebSocket#events)에서) 발생하는 이벤트입니다.
SVGSVG 이미지와 관련된 이벤트입니다.SVGElement, SVGAnimationElement, SVGGraphicsElement에서](https://developer.mozilla.org/en-US/docs/Web/API/SVGGraphicsElement#events)에서) 발생하는 이벤트입니다.
Text selection (텍스트 선택)텍스트 선택과 관련된 Selection API 이벤트입니다.HTMLTextAreaElement, HTMLInputElement에서](https://developer.mozilla.org/en-US/docs/Web/API/HTMLInputElement/selectionchange_event)에서) 발생하는 이벤트(selectionchange)입니다.
Touch (터치)Touch Events API와 관련된 이벤트입니다.

터치스크린(예: 손가락이나 스타일러스 사용)과 상호작용할 때 알림 이벤트를 제공합니다. Force Touch API와는 관련이 없습니다.
Document, Element에서](https://developer.mozilla.org/en-US/docs/Web/API/Element#touch_events)에서) 발생하는 이벤트입니다.
Virtual reality (가상 현실)WebXR Device API와 관련된 이벤트입니다.

> 경고 (Warning): WebVR API(그리고 관련된 Window 이벤트들)은](https://developer.mozilla.org/en-US/docs/Web/API/WebVR_API#window_events))은) 더 이상 권장되지 않습니다(deprecated).
XRSystem, XRSession, XRReferenceSpace에서](https://developer.mozilla.org/en-US/docs/Web/API/XRReferenceSpace#events)에서) 발생하는 이벤트입니다.
RTC (실시간 통신)WebRTC API와 관련된 이벤트입니다.RTCDataChannel, RTCDTMFSender, RTCIceTransport, RTCPeerConnection에서](https://developer.mozilla.org/en-US/docs/Web/API/RTCPeerConnection#events)에서) 발생하는 이벤트입니다.
Server-sent events (서버 전송 이벤트)Server sent events API와 관련된 이벤트입니다.EventSource에서](https://developer.mozilla.org/en-US/docs/Web/API/EventSource#events)에서) 발생하는 이벤트입니다.
Speech (음성)Web Speech API와 관련된 이벤트입니다.SpeechSynthesisUtterance에서](https://developer.mozilla.org/en-US/docs/Web/API/SpeechSynthesisUtterance#events)에서) 발생하는 이벤트입니다.
Workers (워커)Web Workers API, Service Worker API, Broadcast Channel API, 그리고 Channel Messaging API와 관련된 이벤트입니다.

새로운 메시지나 메시지 전송 에러에 응답하기 위해 사용됩니다. 서비스 워커(Service workers)는 푸시 알림, 사용자의 표시된 알림 클릭, 푸시 구독 무효화, 콘텐츠 인덱스에서 항목 삭제 등 다른 이벤트에 대해서도 알림을 받을 수 있습니다.
ServiceWorkerGlobalScope, DedicatedWorkerGlobalScope, SharedWorkerGlobalScope, WorkerGlobalScope, Worker, BroadcastChannel, MessagePort에서](https://developer.mozilla.org/en-US/docs/Web/API/MessagePort#events)에서) 발생하는 이벤트입니다.

이벤트 생성 및 발생시키기 (Creating and dispatching events)

내장된 인터페이스들이 스스로 발생시키는 이벤트 외에도, 우리가 직접 DOM 이벤트를 만들고 발생(dispatch)시킬 수도 있어요. 이렇게 코드에서 만든 이벤트들은 브라우저가 발생시키는 이벤트와 구분하기 위해 보통 합성 이벤트(synthetic events) 라고 부른답니다.

커스텀 이벤트 만들기 (Creating custom events)

이벤트는 다음과 같이 Event 생성자를 사용해서 만들 수 있어요:

const event = new Event("build");

// 이벤트를 리스닝합니다.
elem.addEventListener("build", (e) => {
  /* … */
});

// 이벤트를 발생(Dispatch)시킵니다.
elem.dispatchEvent(event);

이 코드 예제에서는 EventTarget.dispatchEvent() 메서드를 활용하고 있어요.

커스텀 데이터 추가하기 – CustomEvent()

이벤트 객체에 더 많은 데이터를 담아 넘기고 싶을 때는 CustomEvent 인터페이스를 사용하면 돼요. 이 인터페이스가 제공하는 detail 속성을 이용하면 원하는 커스텀 데이터를 전달할 수 있거든요.
예를 들어, 이벤트는 다음과 같이 생성할 수 있습니다:

const event = new CustomEvent("build", { detail: elem.dataset.time });

이렇게 하면 이벤트 리스너 안에서 방금 담아둔 추가 데이터에 접근할 수 있게 됩니다:

function eventHandler(e) {
  console.log(`The time is: ${e.detail}`);
}

커스텀 데이터 추가하기 – Event 클래스 상속하기 (subclassing Event)

Event 인터페이스를 상속(subclass)해서 만들 수도 있어요. 이 방식은 코드를 재사용하거나, 훨씬 복잡한 커스텀 데이터를 다루거나, 아예 이벤트 객체 안에 메서드를 추가하고 싶을 때 특히 유용합니다.

class BuildEvent extends Event {
  #buildTime;

  constructor(buildTime) {
    super("build");
    this.#buildTime = buildTime;
  }

  get buildTime() {
    return this.#buildTime;
  }
}

이 코드는 읽기 전용 속성과 고정된 이벤트 타입("build")을 가진 BuildEvent라는 클래스를 정의한 예제예요.

이제 이 이벤트는 아래처럼 생성할 수 있어요:

const event = new BuildEvent(elem.dataset.time);

그리고 이벤트 리스너에서는 이렇게 우리가 만든 커스텀 속성을 이용해 추가 데이터에 접근하면 됩니다:

function eventHandler(e) {
  console.log(`The time is: ${e.buildTime}`);
}

이벤트 버블링 (Event bubbling)

종종 자식 요소에서 이벤트를 트리거(발생)시키고 그걸 상위 조상 요소가 잡아채서(캐치해서) 처리하게 만들고 싶을 때가 있죠? 원한다면 이때 이벤트에 데이터를 함께 담아서 보낼 수도 있어요:

<form>
  <textarea></textarea>
</form>
const form = document.querySelector("form");
const textarea = document.querySelector("textarea");

// 새로운 이벤트를 생성하고, 버블링을 허용하며, "detail" 속성에 전달하고 싶은 데이터를 넘겨줍니다.
const eventAwesome = new CustomEvent("awesome", {
  bubbles: true,
  detail: { text: () => textarea.value },
});

// form 요소는 커스텀 "awesome" 이벤트를 리스닝하다가, 이벤트가 발생하면 전달받은 text() 메서드의 결과를 콘솔에 출력합니다.
form.addEventListener("awesome", (e) => console.log(e.detail.text()));

// 사용자가 타이핑을 할 때마다, form 안의 textarea는 자기 자신을 시작점으로 삼아 해당 이벤트를 발생(dispatch/trigger)시킵니다.
textarea.addEventListener("input", (e) => e.target.dispatchEvent(eventAwesome));

동적으로 이벤트 생성 및 발생시키기 (Creating and dispatching events dynamically)

요소들은 아직 생성되지도 않은 이벤트를 리스닝할 수 있어요:

<form>
  <textarea></textarea>
</form>
const form = document.querySelector("form");
const textarea = document.querySelector("textarea");

form.addEventListener("awesome", (e) => console.log(e.detail.text()));

textarea.addEventListener("input", function () {
  // 이벤트 객체를 생성하자마자 즉석에서 바로 발생시킵니다.
  // 참고: 여기서 ("화살표 함수" 대신) 일반적인 "함수 표현식(function expression)"을 사용했기 때문에 함수 안의 "this"는 이벤트가 발생한 대상 요소(textarea)를 가리키게 됩니다.
  this.dispatchEvent(
    new CustomEvent("awesome", {
      bubbles: true,
      detail: { text: () => textarea.value },
    }),
  );
});

내장 이벤트 발생시키기 (Triggering built-in events)

이 예제는 DOM 메서드를 사용해서 체크박스에 대한 클릭 동작을 시뮬레이션(즉, 프로그래밍 방식으로 클릭 이벤트를 강제 생성)하는 방법을 보여줍니다. 이 예제가 실제로 작동하는 모습을 확인해 보세요.

function simulateClick() {
  const event = new MouseEvent("click", {
    view: window,
    bubbles: true,
    cancelable: true,
  });
  const cb = document.getElementById("checkbox");
  const cancelled = !cb.dispatchEvent(event);

  if (cancelled) {
    // 핸들러 중 누군가가 preventDefault를 호출했습니다.
    alert("cancelled");
  } else {
    // 아무 핸들러도 preventDefault를 호출하지 않았습니다.
    alert("not cancelled");
  }
}

이벤트 핸들러 등록하기 (Registering event handlers)

핸들러를 등록할 때 권장하는 방식은 두 가지예요. 이벤트 핸들러 코드가 이벤트 발생 시 실행되도록 하려면 대상 요소의 상응하는 onevent 속성에 코드를 할당하거나, 아니면 addEventListener() 메서드를 써서 해당 요소에 리스너로 핸들러를 등록하면 됩니다.

어떤 방식을 쓰든 핸들러는 첫 번째 인자로 Event 인터페이스 (또는 거기서 파생된 인터페이스) 규격을 따르는 객체를 넘겨받게 돼요. 두 방식의 가장 큰 차이점은, 이벤트 리스너 메서드(addEventListener)를 사용하면 하나의 이벤트에 여러 개의 핸들러를 추가(또는 제거)할 수 있다는 점이에요.

경고 (Warning):
HTML의 인라인 onevent 속성을 사용해서 이벤트 핸들러를 설정하는 세 번째 방식은 권장하지 않습니다! 이렇게 작성하면 HTML 마크업이 지저분해져서 읽기 힘들어지고 디버깅하기도 까다로워지거든요. 더 자세한 정보는 인라인 이벤트 핸들러 - 사용하지 마세요(Inline event handlers) 부분을 참고해 주세요.

onevent 속성 사용하기 (Using onevent properties)

관례적으로, 이벤트를 발생시키는 자바스크립트 객체들은 그에 대응하는 "onevent" 속성을 가지고 있어요. (이벤트 이름 앞에 "on"이 붙은 형태죠). 이런 속성들은 이벤트가 발생했을 때 연결된 핸들러 코드를 실행하기 위해 호출되며, 여러분의 코드에서 직접 호출할 수도 있습니다.

이벤트 핸들러 코드를 세팅하려면 그냥 해당하는 onevent 속성에 함수를 할당해주면 됩니다. 단, 이 방식은 하나의 요소에서 각 이벤트당 오직 하나의 핸들러만 지정할 수 있어요. 만약 핸들러를 바꾸고 싶다면 같은 속성에 다른 함수를 다시 할당해서 덮어씌워야 한답니다.

다음 예제는 onclick 속성을 사용해서 click 이벤트에 greet() 함수를 설정하는 방법을 보여줍니다.

const btn = document.querySelector("button");

function greet(event) {
  console.log("greet:", event);
}

btn.onclick = greet;

여기서 명심할 점은, 이벤트를 나타내는 객체가 이벤트 핸들러의 첫 번째 인자로 전달된다는 거예요. 이 이벤트 객체는 Event 인터페이스를 구현하고 있거나 거기서 파생된 객체입니다.

EventTarget.addEventListener

요소에 이벤트 핸들러를 설정하는 가장 유연한 방법은 EventTarget.addEventListener 메서드를 사용하는 거예요. 이 접근법을 쓰면 하나의 요소에 여러 개의 리스너를 달 수 있고, 필요하다면 EventTarget.removeEventListener를](https://developer.mozilla.org/en-US/docs/Web/API/EventTarget/removeEventListener)를) 써서 리스너를 제거할 수도 있습니다.

참고 (Note):
이벤트 핸들러를 추가하고 제거할 수 있다는 건 상당히 유용해요. 예를 들어 같은 버튼이라도 상황에 따라 전혀 다른 동작을 수행하게 만들 수 있죠. 게다가 좀 더 복잡한 프로그램에서는 오래되거나 안 쓰는 이벤트 핸들러를 깔끔하게 지워줌으로써 메모리 효율을 높일 수도 있습니다.

다음 예제는 greet() 함수를 click 이벤트를 위한 리스너/핸들러로 어떻게 세팅하는지 보여줍니다. (꼭 이름이 있는 함수가 아니더라도 원한다면 익명 함수 표현식을 사용해도 괜찮아요). 아까와 마찬가지로, 이벤트 객체가 이벤트 핸들러의 첫 번째 인자로 전달된다는 걸 기억해 주세요.

const btn = document.querySelector("button");

function greet(event) {
  console.log("greet:", event);
}

btn.addEventListener("click", greet);

이 메서드는 이벤트가 어떻게 캡처(capture)되고 제거될지에 대한 측면을 세밀하게 제어하기 위해 추가적인 인자나 옵션 객체를 받을 수도 있어요. 자세한 정보는 EventTarget.addEventListener 레퍼런스 페이지에서 찾아보실 수 있습니다.

AbortSignal 사용하기 (Using AbortSignal)

이벤트 리스너의 눈여겨볼 만한 기능 중 하나는 중단 신호(abort signal)를 사용해서 여러 이벤트 핸들러를 한꺼번에 싹 정리(clean up)할 수 있는 능력이에요.

이 기능은 함께 묶어서 제거하고 싶은 모든 이벤트 핸들러의 addEventListener() 호출에 똑같은 AbortSignal을](https://developer.mozilla.org/en-US/docs/Web/API/AbortSignal)을) 넘겨주는 방식으로 동작해요. 그러고 나서 해당 AbortSignal을 관리하는 컨트롤러 객체에 있는 abort() 메서드를 호출하면, 그 신호와 함께 추가되었던 모든 이벤트 핸들러들이 한 방에 지워집니다. 예를 들어, 나중에 AbortSignal로 제거할 수 있는 이벤트 핸들러를 추가해 볼까요:

const controller = new AbortController();

btn.addEventListener(
  "click",
  (event) => {
    console.log("greet:", event);
  },
  { signal: controller.signal },
); // 이 핸들러에 AbortSignal을 전달합니다.

이렇게 달아둔 이벤트 핸들러는 아래와 같이 제거할 수 있어요:

controller.abort(); // 이 컨트롤러와 연결된 모든 이벤트 핸들러를 제거합니다.

여러 이벤트 핸들러의 상호작용 (Interaction of multiple event handlers)

onevent IDL 속성 (예: element.onclick = ...)과 HTML onevent 콘텐츠 속성 (예: <button>)은 둘 다 똑같은 단 하나의 핸들러 슬롯을 타겟으로 삼아요. 보통 HTML이 먼저 로드되고 그 후에 자바스크립트가 동일한 요소에 접근하기 때문에, 결과적으로 자바스크립트 코드가 HTML에 명시된 핸들러를 덮어쓰게(replace) 되는 게 일반적입니다. 하지만 addEventListener()로](https://developer.mozilla.org/en-US/docs/Web/API/EventTarget/addEventListener)로) 추가된 핸들러들은 이들과 완전히 독립적이에요. 즉, onevent 속성을 사용한다고 해서 addEventListener()로 추가된 리스너가 제거되거나 덮어씌워지지 않고, 그 반대도 마찬가지입니다.

이벤트가 발생(디스패치)될 때, 리스너들은 여러 단계(phases)를 거치며 호출되는데요. 여기엔 캡처(capture)버블(bubble) 이라는 두 가지 단계가 있습니다. 캡처 단계에서는 이벤트가 DOM 트리의 가장 높은 조상 요소에서 시작해서 타겟 요소에 도달할 때까지 아래로 내려갑니다. 반대로 버블 단계에서는 이벤트가 타겟에서 시작해 반대 방향(위쪽)으로 타고 올라가죠. 이벤트 리스너들은 기본적으로 버블 단계에서 이벤트를 감지하게 되어있는데, 만약 addEventListener()를 호출할 때 capture: true 옵션을 주면 캡처 단계에서 감지하도록 만들 수도 있습니다. 같은 단계 안에서는 리스너들이 등록된 순서대로 실행돼요. onevent 핸들러의 경우, 처음에 null이 아닌 값이 들어가는 순간 등록되며, 나중에 다시 다른 함수를 할당하더라도 실행 순서(position) 자체는 바뀌지 않고 오직 콜백 함수 내용만 바뀝니다.

이러한 전파 과정 중에 Event.stopPropagation()을](https://developer.mozilla.org/en-US/docs/Web/API/Event/stopPropagation)을) 호출하면, 전파 체인의 뒤이어질 요소들에 붙은 다른 리스너들이 호출되는 것을 막을 수 있습니다. 또한 Event.stopImmediatePropagation()을](https://developer.mozilla.org/en-US/docs/Web/API/Event/stopImmediatePropagation)을) 호출하면 심지어 현재 동일한 요소에 붙어있던 나머지 리스너들까지도 마저 실행되는 걸 막을 수 있답니다.

profile
프론트에_가까운_풀스택_개발자

0개의 댓글