이벤트 단계(Event Phase)

표준 DOM 이벤트 흐름은 3가지 단계가 있습니다.
- 캡처링 단계 - 이벤트가 하위 요소로 전파되는 단계
- 타겟 단계 - 이벤트가 실제 타겟 요소에 전달되는 단계
- 버블링 단계 - 이벤트가 상위 요소로 전파되는 단계
캡쳐링 단계
브라우저에서 이벤트가 발생하면, 가장 먼저 이벤트 발생 지점을 찾습니다.
- 이벤트가 하위 요소(element)로 전파되는 단계입니다.
- window → document → html → body → … 순으로 해당 자녀까지 내려갑니다.
- 이 과정 중 만나는 모든 자녀의 ‘캡쳐링’ 이벤트 리스너를 실행합니다.
타겟 단계
이벤트가 실제 타깃 요소에 전달되는 단계입니다.
버블링 단계
이벤트 발생 지점에서 DOM Tree를 따라 다시 window까지 올라갑니다.
- 이벤트가 상위 요소로 전파되는 단계입니다.
- 이 과정 중 만나는 모든 자녀의 ‘버블링’ 이벤트 리스너를 실행합니다.
이벤트 전파 제어 - 버블링과 캡쳐링
버블링
이벤트 등록은el.addEventListener(event, handler, {capture: false}) 형태로 합니다.
*{capture: false}는 default이므로, 생략하거나 false로 줄일 수 있습니다.
// *p태그는 input 태그를 감싸고 있는 형태입니다.
// *p태그와 input 태그에 모두 버블링 이벤트 리스너를 등록했습니다.
<body>
<p>
<input type="submit"/>
</p>
</body>
<script>
const p = document.querySelector("p");
const input = document.querySelector("input");
p.addEventListener("click", () => {
console.log("p태그 클릭");
});
span.addEventListener("click", (e) => {
console.log("input태그 클릭");
});
</script>
p태그 영역을 클릭하면 ‘p태그 클릭’이 출력됩니다.
input태그 영역을 클릭하면 ‘input태그 클릭’만 출력되지 않고 다음 순서대로 출력됩니다.
- ‘input태그 클릭’ 출력
- ‘p태그 클릭’ 출력
이벤트 버블링은 발생한 이벤트 지점에서 부모로 올라가면서 만나는 모든 이벤트리스너를 실행하기 때문입니다.
input태그에서 이벤트가 발생하여 올라갈(버블링) 때 만난 p태그의 (버블링)이벤트 리스너를 실행한 것입니다.
input 태그 클릭 시 p태그로 이벤트 전파(버블링)되지 않게 하려면?
전파가 멈출 이벤트리스너에 stopPropagation을 사용합니다.
input.addEventListener("click", (e) => {
console.log("input태그 클릭");
e.stopPropagation();
});
input 태그에서 버블링을 멈추도록 했으니, 상위 엘리먼트인 p태그 부터는 버블링이 되지 않습니다.
뒤에 실행될 모든 이벤트리스너를 막아버릴 수도 있다.
stopImmediatePropagation을 사용한다.
이벤트 버블링 뿐만 아니라 캡쳐링까지 모두 막는다.
input.addEventListener("click", (e) => {
e.stopImmediatePropagation();
console.log("1");
});
input.addEventListener("click", (e) => {
console.log("2");
});
input.addEventListener("click", (e) => {
console.log("3");
});
캡쳐링
이벤트 등록은el.addEventListener(event, handler, {capture: true}) 형태로 합니다.
*{capture: true}는 true로 줄일 수 있습니다.
const p = document.querySelector("p");
const input = document.querySelector("input");
p.addEventListener(
"click",
() => {
console.log("p태그 클릭");
},
true
);
input.addEventListener("click", (e) => {
console.log("input태그 클릭");
});
input태그 영역을 클릭하면 ‘input태그 클릭’만 출력되지 않고 다음 순서대로 출력됩니다.
- ‘p태그 클릭’ 출력
- ‘input태그 클릭’ 출력
p태그에 등록된 리스너는 캡쳐링을 하기 때문에 input 태그로 내려갈 때 실행됩니다.
[참고 자료]
'Javascript' 카테고리의 다른 글
| 타입 추론 / 단언 / 가드 (1) | 2024.04.12 |
|---|---|
| 함수형프로그래밍 (0) | 2024.04.11 |
| 번들러 (0) | 2024.04.11 |
| 프로미스와 Async / await (0) | 2024.04.11 |
| 프로토타입 (1) | 2024.04.11 |