학습
JavaScript DOM 이벤트 전파 이해
JavaScript DOM 이벤트 전파 이해 — 중급
DOM 이벤트 전파 이해
1. 도입 (왜 배워야 하는가)
DOM 이벤트 전파는 웹 개발에서 매우 중요한 개념입니다. 웹 페이지에서 사용자와 상호작용할 때 발생하는 다양한 이벤트(클릭, 입력, 스크롤 등)는 DOM을 통해 전파됩니다. 이 과정을 이해하지 못하면, 이벤트 처리에서 의도치 않은 동작이나 성능 문제를 초래할 수 있습니다. 예를 들어, 버튼 클릭 시 부모 요소의 이벤트 핸들러가 실행되도록 설정했는데, 이를 잘못 이해하면 원치 않는 결과를 가져올 수 있습니다. 따라서, 이벤트 전파를 이해하고 적절히 활용하는 것은 안정적이고 효율적인 웹 애플리케이션 개발에 필수적입니다.
2. 핵심 개념 설명
이벤트 전파(Event Propagation)
이벤트 전파는 이벤트가 발생한 요소에서 부모 요소로 전달되는 과정을 말합니다. 주로 두 가지 단계로 나뉩니다:
- 캡처링 단계 (Capturing): 이벤트가 최상위 부모 요소에서 시작하여 이벤트가 발생한 요소로 내려가는 단계입니다.
- 버블링 단계 (Bubbling): 이벤트가 발생한 요소에서 시작하여 최상위 부모 요소로 올라가는 단계입니다.
- 자식 버튼 클릭 시 "자식 버튼 클릭!" 알림이 뜨고, 이후 "부모 요소 클릭!" 알림은 뜨지 않습니다.
- HTML 문서 구조가 로드됩니다.
- 부모 요소에 클릭 이벤트 리스너가 추가됩니다.
- 자식 버튼에 클릭 이벤트 리스너가 추가됩니다.
- 사용자가 자식 버튼을 클릭하면, 자식 버튼의 이벤트 리스너가 실행되어 "자식 버튼 클릭!" 알림이 표시됩니다.
event.stopPropagation()이 호출되어 이벤트가 부모 요소로 전파되는 것을 막습니다.- 잘못된 코드
- 올바른 코드
- 이벤트 리스너가 중복 등록되면, 같은 이벤트가 여러 번 실행될 수 있습니다.
removeEventListener를 사용하여 기존 리스너를 제거하는 것이 좋습니다. - DOM 이벤트 전파는 웹 페이지에서 이벤트가 어떻게 흐르는지를 이해하는 데 필수적입니다.
- 캡처링과 버블링 단계로 나뉘며 각각의 사용 사례가 있습니다.
- 이벤트 전파를 제어할 수 있는 방법으로
stopPropagation()이 있습니다. - 실무에서 장바구니 구현과 폼 제출 처리 시 유용하게 사용됩니다.
- 다음에 학습하면 좋은 주제로는 이벤트 위임(Event Delegation)과 비동기 처리(Async Handling)를 추천합니다.
비유
이를 실생활 비유로 설명하자면, 큰 행사에서 마이크를 통해 질문을 하는 상황을 상상해보세요. 질문이 시작될 때, 사회자가 마이크를 잡고 관객에게 질문을 한 후, 질문이 해당 주제의 전문가에게 전달됩니다. 질문이 전달되는 과정이 캡처링 단계라면, 전문가가 대답을 한 후 다시 사회자를 통해 관객에게 전달되는 과정이 버블링 단계입니다.
관련 용어 정리
| 용어 | 설명 |
|---|---|
| 이벤트 | 사용자와 웹 페이지 간의 상호작용을 나타냄 |
| 핸들러 | 특정 이벤트가 발생했을 때 실행되는 함수 |
| 캡처링 | 이벤트가 최상위에서 하위로 전달되는 과정 |
| 버블링 | 이벤트가 하위에서 상위로 전달되는 과정 |
3. 기본 코드 예제
아래는 간단한 HTML 요소에서 이벤트 전파를 보여주는 코드입니다.
<!DOCTYPE html>
<html lang="ko">
<head>
<meta charset="UTF-8">
<title>이벤트 전파</title>
</head>
<body>
<div id="parent" style="padding: 20px; background-color: lightgray;">
부모 요소
<button id="child">자식 버튼</button>
</div>
<script>
document.getElementById('parent').addEventListener('click', function() {
alert('부모 요소 클릭!');
});
document.getElementById('child').addEventListener('click', function(event) {
alert('자식 버튼 클릭!');
// 이벤트 전파 중단
event.stopPropagation();
});
</script>
</body>
</html>
실행 결과
코드 한 줄씩 동작 설명
4. 실전 활용 예제
예제 1: 쇼핑몰 장바구니 구현
쇼핑몰에서 장바구니 버튼을 클릭했을 때, 해당 제품 정보를 부모 요소에 전달하여 장바구니에 추가하는 경우를 생각해보겠습니다.
<div id="cart">
<div class="product" data-id="1">제품 1<button class="add-to-cart">장바구니에 추가</button></div>
<div class="product" data-id="2">제품 2<button class="add-to-cart">장바구니에 추가</button></div>
</div>
<script>
document.getElementById('cart').addEventListener('click', function(event) {
if (event.target.classList.contains('add-to-cart')) {
const productId = event.target.parentElement.dataset.id;
console.log(제품 ID ${productId}이(가) 장바구니에 추가되었습니다.);
}
});
</script>
예제 2: 폼 제출 처리
사용자가 폼을 제출할 때, 유효성 검사를 수행하고 문제가 없을 경우에만 부모 요소로 이벤트를 전파하여 데이터를 전송할 수 있습니다.
<form id="myForm">
<input type="text" required />
<button type="submit">제출</button>
</form>
<script>
document.getElementById('myForm').addEventListener('submit', function(event) {
if (!this.checkValidity()) {
event.preventDefault(); // 유효성 검사 실패 시 제출 방지
alert('모든 필드를 채워주세요.');
} else {
alert('폼이 제출되었습니다.');
}
});
</script>
5. 흔한 실수와 주의사항
실수 1: 이벤트 전파 중단을 잊기
document.getElementById('child').addEventListener('click', function() {
alert('자식 버튼 클릭!');
});
document.getElementById('child').addEventListener('click', function(event) {
alert('자식 버튼 클릭!');
event.stopPropagation(); // 이벤트 전파 중단
});