[JS] 이벤트 (Event)

artp·2025년 4월 10일

javascript

목록 보기
3/50
post-thumbnail

웹 페이지는 사용자의 행동에 따라 반응해야 진짜 인터랙티브한 "웹 애플리케이션"이 됩니다.
버튼을 클릭하고, 마우스를 올리고, 키보드를 입력하는 등 사용자의 행동을 감지하고, 그에 따라 코드를 실행시키는 것이 자바스크립트 이벤트의 역할입니다.

이벤트(Event)란?

이벤트는 브라우저에서 발생한 사용자의 행동 또는 브라우저 자체의 변화를 뜻합니다.

예를 들어,

  • 버튼 클릭 → click 이벤트
  • 마우스를 올림 → mouseover 이벤트
  • 키보드 입력 → keydown 이벤트
  • 폼 제출 → submit 이벤트

이런 사건들(Event)이 발생했을 때, 개발자가 미리 등록해 둔 코드(이벤트 핸들러)가 실행됩니다.

이벤트 리스너(Event Listener)란?

이벤트가 발생했을 때, 자바스크립트가 무언가를 실행하려면 그 이벤트가 발생하는지 감시하는 역할이 필요합니다.
그 역할을 하는 것이 바로 이벤트 리스너(Event Listener)입니다.

즉, "이벤트가 발생하면 이 함수를 실행해줘!"라고 브라우저에 알려주는 것이 이벤트 리스너입니다.

이벤트 리스너와 이벤트 핸들러의 차이

용어역할예시
이벤트 리스너특정 이벤트가 발생했는지를 감시하고, 발생 시 실행할 함수를 등록함 (개념상 구조)element.addEventListener("click", handler);
이벤트 핸들러이벤트가 발생했을 때 실제로 실행되는 함수function handler(e) { ... }

실무에서는 이 둘을 거의 동일하게 쓰지만,
엄밀히 말하면 이벤트 리스너는 “감시 대상과 실행 함수가 연결된 상태”,
이벤트 핸들러는 “실행되는 함수 그 자체”입니다.

자바스크립트에서 이벤트 리스너 등록하기

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

function handleClick(event) {
	alert("버튼이 클릭되었습니다!");
}

// 이벤트 리스너 등록 (리스너 + 핸들러 연결)
button.addEventListener("click", handleClick);
  • "click" 이벤트를 감시하는 리스너를 등록
  • 실제로 클릭이 발생하면 handleClick()이 실행됨 → 이게 핸들러

한 번만 실행되는 리스너

한 번만 실행되는 리스너도 가능합니다.

button.addEventListener("click", handleClick, { once: true });
  • 이 리스너는 클릭 한 번 이후 자동으로 제거됩니다.

리스너 제거하기

리스너를 제거할 수 있습니다.

button.removeEventListener("click", handleClick);
  • addEventListener()로 등록한 리스너는 removeEventListener()로 제거 가능
  • removeEventListener()는 내부적으로 리스너 테이블에서 정확히 일치하는 리스너를 찾아 제거
  • 등록할 때와 제거할 때 동일한 함수 객체를 참조하게 되어야 정상적으로 제거됨
  • 단, 익명 함수는 제거 불가

removeEventListener()는 내부적으로
브라우저의 리스너 테이블에서 “같은 함수 객체”를 찾아 제거합니다.
익명 함수는 등록할 때와 제거할 때 서로 다른 참조가 되기 때문에 일치하지 않아 제거되지 않습니다.

이벤트를 등록하는 방법

1. HTML에 직접 속성으로 작성하기 (인라인 방식, 비추천)

<button onclick="alert('클릭!')">클릭하세요</button>
  • 간단하지만 유지보수/재사용성이 떨어짐
  • JS와 HTML이 분리되지 않음

2. DOM 요소에 직접 등록하기 (DOM 속성 방식)

const btn = document.querySelector("button");
btn.onclick = function () {
  alert("클릭됨!");
}
  • 한 번만 등록 가능 (기존 핸들러 덮어씀)
  • 간단한 상황에서 사용

3. addEventListener() 사용하기 (가장 추천되는 방식)

btn.addEventListener("click", function () {
  alert("이벤트 리스너 실행!");
});
  • 여러 개의 핸들러 등록 가능
  • removeEventListener로 제거 가능
  • 이벤트 전파 제어 가능
  • 실무에서는 대부분 addEventListener()를 사용

이벤트 객체(Event Object)

이벤트가 발생하면 브라우저는 자동으로 이벤트 객체(event object)를 핸들러 함수에 전달합니다.
이벤트 객체는 해당 이벤트에 관련한 모든 정보를 가지고 있습니다.

btn.addEventListener("click", function (event) {
  console.log("이벤트 종류:", event.type);	// click
  console.log("발생한 요소:", event.target);	// <button>
});
  • 이벤트가 처리되고 나면 이벤트 객체는 자동으로 소멸합니다.

이벤트 객체 내에는 다음과 같은 정보들이 들어 있습니다.

속성설명
event.type이벤트의 종류 (click, submit 등)
event.target이벤트가 발생한 실제 요소
event.currentTarget현재 이벤트 리스너가 붙은 요소
event.preventDefault()기본 동작 방지 (예: form 제출 방지)
event.stopPropagation()이벤트 전파 막기 (버블링 차단)

자주 사용하는 이벤트 종류

이벤트설명
click클릭할 때
dblclick더블 클릭
mouseover / mouseout마우스를 올릴 때 / 뗄 때
keydown / keyup키보드 입력 시
input입력창 내용 실시간 변경 시
change<select>, <checkbox> 등 값 변경 시
submit폼 제출 시
DOMContentLoaded문서 구조(DOM)가 로드되었을 때

PreventDefault vs stopPropagation

메서드역할상황예시
preventDefault()브라우저의 기본 동작을 막음링크 클릭 시 이동 막기, 폼 제출 시 새로고침 막기 등e.preventDefault();
stopPropagation()이벤트가 부모 요소로 전파되는 것을 막음부모/자식 요소 둘 다 리스너가 있을 때, 자식 이벤트만 실행되게 하고 싶을 때 등e.stopPropagation();

예시로 이해하기

<a href="https://google.com" id="link">구글로 이동</a>
<script>
  document.getElementById("link").addEventListener("click", function (e) {
    e.preventDefault(); // 링크 이동 막기
    alert("링크 클릭은 됐지만, 이동은 안 해요!");
  });
</script>
  • preventDefault() 사용 예시 → 클릭은 되지만, 링크 이동은 안 함
<div id="parent">
  <button id="child">눌러봐요</button>
</div>

<script>
  document.getElementById("parent").addEventListener("click", () => {
    alert("부모 div 클릭됨");
  });

  document.getElementById("child").addEventListener("click", (e) => {
    e.stopPropagation(); // 이벤트 전파 막기
    alert("버튼만 클릭됨 (부모는 무시됨)");
  });
</script>
  • stopPropagation() 사용 예시 → 버튼만 반응하고, 부모 div는 클릭된 것처럼 보이지 않음

이벤트 흐름: 캡처링 & 버블링

브라우저는 이벤트가 발생했을 때 “어느 요소에서 발생했는지”만 보는 게 아니라,
이벤트를 위에서부터 아래로, 그리고 다시 아래에서 위로 이동시키며 처리합니다.

이벤트 흐름 2단계

1. 캡처링(Capturing)

  • 이벤트가 window 객체에서 중간의 모든 DOM 객체를 거쳐 타겟 객체에 전달되는 과정
  • 이벤트가 거쳐가는 모든 DOM 객체(window포함)의 이벤트 리스너 실행
  • 가장 바깥쪽(문서, body 등)에서 시작해서 → 이벤트 발생한 요소까지 내려옴
  • 보통 기본값으로는 사용되지 않음
  • 설정하려면 addEventListener(..., true)처럼 세 번째 인자를 true로 지정해야 함

2. 버블링(Bubbling)

  • 이벤트가 타겟에서 중간의 모든 DOM 객체를 거쳐 window 객체에 전달되는 과정
  • 이벤트가 거쳐가는 모든 DOM 객체(window포함)의 이벤트 리스너 실행
  • 이벤트가 발생한 타겟 요소에서 → 바깥쪽으로 올라감
  • 기본 동작 (브라우저는 대부분의 이벤트를 이 흐름으로 처리함)
  • addEventListener(..., false) 또는 생략하면 버블링 단계에서 실행됨

코드로 설명

html:

<div id="outer">
  <button id="inner">눌러보세요</button>
</div>

JavaScript:

document.getElementById("outer").addEventListener("click", () => {
  console.log("outer");
}, true); // 캡처링 단계

document.getElementById("inner").addEventListener("click", () => {
  console.log("inner");
}); // 버블링 단계
  • 사용자가 버튼을 클릭하면 실행 순서는 이렇습니다:
    1. outer 캡처링 리스너 실행 (캡처링 단계)
    2. inner 버블링 리스너 실행 (버블링 단계)

  • 만약 둘 다 버블링이면 → inner가 먼저, outer가 나중에 실행됨

표: 캡처링&버블링 정리

단계방향기본 적용 여부설정 방법
캡처링바깥 → 안쪽❌ (기본값 아님)addEventListener(..., true)
버블링안쪽 → 바깥✅ (기본값)addEventListener(..., false) 또는 생략
profile
donggyun_ee

0개의 댓글