일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | ||||||
2 | 3 | 4 | 5 | 6 | 7 | 8 |
9 | 10 | 11 | 12 | 13 | 14 | 15 |
16 | 17 | 18 | 19 | 20 | 21 | 22 |
23 | 24 | 25 | 26 | 27 | 28 | 29 |
30 | 31 |
- 자바스크립트
- 렛츠기릿 자바스크립트
- 백준
- 4주 프로젝트
- 타임어택
- HTTP
- 회고
- python
- 파이썬
- 타입스크립트 올인원
- til
- 코드스테이츠
- 타입스크립트
- 정재남
- programmers
- 알고리즘
- 2주 프로젝트
- 토익
- 리트코드
- 코어 자바스크립트
- SQL 고득점 Kit
- codestates
- 프로그래머스
- 리액트
- 제로초
- 손에 익히며 배우는 네트워크 첫걸음
- javascript
- LeetCode
- 리덕스
- js
- Today
- Total
Jerry
#13. 이벤트 전파 본문
이벤트 전파(Event Propagation)는 JavaScript에서
이벤트가 DOM 요소 계층을 따라 이동하는 방식을 설명하는 개념으로,
캡처링(Capturing) 단계, 타깃(Target) 단계, 버블링(Bubbling) 단계의 3단계로 진행됩니다.
1. 이벤트 전파의 개념과 3단계
- 이벤트가 발생하면 브라우저는 특정한 흐름을 따라 이벤트를 전달
1) 캡쳐링 단계 (Capturing Phase)
- 최상위 window 객체에서 시작하여 이벤트 발생 요소까지 DOM 트리를 타고 내려감
- addEventListener의 세 번째 인자로 true를 전달하면 이 단계에서 이벤트 핸들러가 실행
addEventListener는 이벤트 리스너를 등록하는 메서드이며, 이벤트 핸들러(event handler)가 아닙니다.
- 이벤트 핸들러는 이벤트가 발생했을 때 실행되는 함수
- addEventListener는 이벤트가 발생했을 때 실행할 핸들러를 등록하는 메서드
function handleClick() {
console.log("버튼이 클릭됨!");
}
const button = document.getElementById("myButton");
// handleClick은 이벤트 핸들러이며, addEventListener는 이를 등록하는 역할
button.addEventListener("click", handleClick);
2) 타깃 단계 (Target Phase)
- 실제 이벤트가 발생한 요소(타깃 요소)에서 이벤트가 실행되는 단계
3) 버블링 단계 (Bubbling Phase)
- 타깃 요소에서 다시 window 객체 방향으로 DOM 트리를 타고 올라가면서 이벤트가 전달
- 기본적으로 addEventListener를 사용할 때 false를 설정하면 이 단계에서 실행
<div id="parent">
<button id="child">Click Me</button>
</div>
<script>
document.getElementById("parent").addEventListener("click", () => {
console.log("부모 요소 클릭 이벤트 발생!");
});
document.getElementById("child").addEventListener("click", () => {
console.log("자식 요소 클릭 이벤트 발생!");
});
</script>
- 버블링 단계에서는 child 버튼을 클릭하면 먼저 child의 핸들러가 실행되고, 그 후 parent의 핸들러가 실행
- 캡처링 단계에서 실행하려면 addEventListener("click", callback, true);로 설정하면 됨
중요한 포인트!
- 이벤트는 "타깃 요소"에서 발생한다! (타깃 요소 = 클릭한 요소)
- 이벤트 자체는 li.child에서 발생 하지만 부모(ul#parent)가 이벤트를 "대신 감지"하는 것
- 등록은 부모 요소에서 했더라도, 이벤트 자체는 클릭된 요소에서 먼저 발생
- 이때 event.target을 사용하면 원래 이벤트가 발생한 요소(li.child)를 알 수 있음
Q. 이벤트 핸들러(ex. addEventListner)의 세 번째 인자의 불린값으로 이벤트 동작이 캡처링 단계에서 실행되냐 혹은 버블링 단계에서 실행하냐를 선택할 수 있다는데, 어느 단계에서 하는 게 중요한가?
A. 기본값으로, false로 버블링 단계에서 실행되고 있다.
단, 특정 이벤트를
- 1. 부모 요소에서 먼저 처리해야 할 경우
- 2. 버블링 문제를 일으킬 때 캡처링(true)을 사용하면 효과적지만
일반적으로 이벤트 위임을 사용할 때는 버블링을 활용하는 것이 더 직관적이다.
왜 이벤트 위임할 때, 버블링 활용이 직관적이라고 하는걸까?
- 모든 자식 요소에 이벤트 리스너를 개별 등록하는 것은 비효율적
- 자식이 많아질수록 리스너도 많아짐
- 동적으로 추가되는 요소에도 이벤트를 자동으로 적용할 수 있음
- 새로운 요소가 추가되더라도 부모가 이벤트 감지할 수 있음
- 코드 유지보수가 쉬움
- 여러 개 요소가 같은 이벤트 사용할 경우, 부모 요소에서 한 번만 관리하면 됨
버블링을 활용하기 때문에 하위 요소에서 이벤트가 발생해도 부모 요소에서 감지할 수 있는 것!
즉, 캡처링을 사용하면 이벤트 위임이 어려울 수 있다는 뜻이다.
- 캡처링은 이벤트가 상위 요소에서 먼저 실행되므로, 하위 요소의 이벤트 감지 어려움
- 버블링은 자식 요소에서 발생한 이벤트가 부모로 전파되므로 감지 가능
=> 위벤트 위임은 버블링 활용할 때가 더 자연스럽고 직관적으로 동작할 수 있다!
이벤트 전파 제어 (이벤트 중단)
- 이벤트 전파를 중단하는 방법은 stopPropagation() 과 stopImmediatePropagation() 이 있음
1) event.stopPropagation()
- 이벤트가 부모 요소로 전파되는 것을 막아 버블링과 캡처링을 차단
- 동일한 요소 내 다른 이벤트 리스너는 계속 실행
document.getElementById("child").addEventListener("click", (event) => {
event.stopPropagation(); // 부모로 이벤트가 전파되지 않음
console.log("자식 요소 클릭!");
});
2) event.stopImmediatePropagation()
- 같은 요소 내의 다른 이벤트 리스너까지도 실행을 막음
- 같은 요소에 여러 개의 핸들러가 있을 경우 유용
document.getElementById("child").addEventListener("click", (event) => {
event.stopImmediatePropagation();
console.log("이벤트 실행 중단!");
});
document.getElementById("child").addEventListener("click", () => {
console.log("이벤트 실행될까요?");
});
- 위 코드에서 stopImmediatePropagation()을 호출하면 두 번째 핸들러는 실행되지 않음
이벤트 위임 (Event Delegation)
- 이벤트 전파를 이용해 성능을 최적화하는 기법으로, 자식 요소마다 개별적으로 이벤트를 추가하는 대신 부모 요소에서 한 번만 이벤트를 등록하는 방법
장점
- 동적으로 생성된 요소에도 이벤트 적용 가능
- 메모리 사용량 감소 (각 요소마다 이벤트 리스너를 붙이지 않아도 됨)
- 코드 유지보수 용이
<ul id="list">
<li>Item 1</li>
<li>Item 2</li>
<li>Item 3</li>
</ul>
<script>
document.getElementById("list").addEventListener("click", (event) => {
if (event.target.tagName === "LI") {
console.log(`클릭한 요소: ${event.target.textContent}`);
}
});
</script>
- ul 요소에 이벤트를 추가하면 새로운 li 요소가 추가되어도 이벤트 핸들러를 따로 붙일 필요가 없음
추가 개념: once 옵션을 활용한 이벤트 핸들링
- 이벤트 리스너를 한 번만 실행하고 제거할 수 있는 once 옵션을 사용할 수도 있음
document.getElementById("button").addEventListener("click", () => {
console.log("한 번만 실행됩니다!");
}, { once: true });
Q. 이벤트 버블링과 캡처링의 차이점은 무엇인가요?
A. 이벤트 버블링은 이벤트가 발생한 요소에서 시작하여 상위 요소로 전파되는 과정이고, 이벤트 캡처링은 최상의 요소에서 타깃 요소까지 내려가는 과정입니다. 기본적으로 addEventListner의 useCapture 옵션이 false면 버블링 단계에서 실행되고, true이면, 캡처링 단계에서 실행됩니다.
Q. event.stopPropagation()과 event.stopImmediatePropagation()의 차이점은?
A. stopPropagation()은 이벤트 전파를 막지만 같은 요소 내의 다른 이벤트 리스너는 실행됩니다. 반면, stopImmediatePropagation은 현재 요소에서 실행될 다른 이벤트 리스너도 모두 막아버립니다.
Q. 이벤트 위임이란 무엇이며, 언제 사용하는 것이 좋은가요?
A. 이벤트 위임은 부모 요소에 이벤트 리스너를 추가하여 자식 요소들의 이벤트를 처리하는 방식입니다. 새로운 요소가 동적으로 추가되거나, 많은 자식 요소에 개별 이벤트를 추가하는 것이 비효율적일 때 사용하면 성능 최적화가 가능합니다.
'CS > Terminology' 카테고리의 다른 글
#12. 마이크로태스크 큐 vs 태스크 큐 (0) | 2025.03.16 |
---|---|
#11. JavaScript는 어떤 언어일까? (0) | 2025.03.15 |
#10. LocalStorage vs SessionStorage vs Cookie (0) | 2025.03.13 |
#9. this 용법 (0) | 2025.03.11 |
#8. SSR vs CSR (0) | 2025.03.10 |