이벤트 버블링에 대해 알기 이전에 용어를 정확히해두고 싶어
흔히 쓰이는 이벤트 리스너와 이벤트 핸들러가 진정 의미하는 것은 무엇인지 대해 알아보았다.
이벤트 리스너와 이벤트 핸들러를 합쳐 이벤트 리스너 혹은 이벤트 핸들러라고 한다.
하지만, 이를 정확하게 말하자면 이벤트 리스너에 등록된 콜백함수가 이벤트 핸들러이다.
div.onClick(() => {});
div.addEventListener('click', () => {});
이벤트 | 이벤트 속성 (이벤트 리스너) | 이벤트 핸들러 |
---|---|---|
click | addEventListener() , onClick() | function(){} |
- ⬇ 하위 요소에 이벤트 전파 캡처링
- 💌 타깃 요소에 이벤트 전달
- ⬆ 상위 요소로 다시 이벤트 전파 버블링
🧼 이벤트 버블링이란?
특정 요소에서 이벤트가 발생됐을 때, 해당 이벤트가 상위 요소들로 전달되어 가는 특성을 말한다.
document
객체를 만날 때까지, 각 요소에 할당된 onClick
이 동작p
> div
> form
이벤트가 제일 깊은 곳의 요소에서부터 시작해 부모 요소를 거슬러 올라가며 이벤트가 발생하는 모양이 마치 물속 거품(bubble)과 같기 때문이다.
event.target
과 event.currentTraget
의 차이점event.target
을 통해 접근 가능하다.event.currentTarget
와 this
event.currentTarget
은 this
와 같다.<!--HTML-->
<form>
FORM
<div>
DIV
<p>P</p>
</div>
</form>
// JavaScript
function lalala(e) {
console.dir(this); // div
console.log(e) // PointerEvent{}
console.log(e.target); // <P>P</P>
console.log(e.currentTarget); <div>...</div>
console.log(e.currentTarget === this); true
}
const divTest = document.querySelector("div");
divTest.addEventListener("click", lalala);
event.currentTarget
event.target
과 event.currentTarget
은 어떻게 다를까?
event.target
: form 안쪽에 내가 실제 클릭한 요소event.currentTarget
: form 요소
event.stopPropagation()
거의 대부분의 이벤트는 버블링되지만, 몇몇 버블링이되지 않는 이벤트도 있다.
(예) focus()
📸 이벤트 캡쳐란?
- 이벤트 버블링과 반대되는 방법
- 이벤트 핸들러 호출 과정의 캡처링 과정에서 이벤트를 잡아내는 방법
form
, div
, p
태그에 모두 click 이벤트를 설정해놓았다고 했을 때, 어떤 순서로 동작하게 될까?
p
클릭HTML
→BODY
→FORM
→DIV
캡쳐링p
타깃요소에 이벤트 전달DIV
→FORM
→BODY
→HTML
버블링
false
: default 값으로, 이벤트 핸들러가 버블링 단계에서 동작한다.true
: 이벤트 핸들러가 캡처링 단계에서 동작한다.div.addEventListener('click', () => {}, { capture: true }); // (1)
div.addEventListener('click', () => {}, true); // (2)
🎁 이벤트 위임이란?
- 이벤트 캡처링과 이벤트 버블링을 활용한 패턴
- 하위 요소🧑🏻마다 이벤트를 등록하지 않고도
하위 요소🧑🏻들의 공통된 부모 요소👵🏻에 이벤트를 등록하여
하위 요소🧑🏻의 이벤트들을 관리하는 방식이다.
<!--HTML-->
<ul>
<li>1</li>
<li>2</li>
<li>3</li>
<li>4</li>
<li>5</li>
<li>6</li>
</ul>
// JavaScript
const li = document.querySelectorAll("li");
li.forEach((li) => {
li.addEventListener("click", () => {
li.classList.add("selected");
});
});
// JavaScript
const ul = document.querySelector("ul");
ul.addEventListener("click", (event) => {
if (event.target.tagName == "LI") {
event.target.classList.add("selected");
}
});
여러 자식 요소에 모두 이벤트를 등록하는 것이 아닌,
부모 요소 하나에 등록함으로써 관리하기 때문에
- 이벤트 핸들러의 관리가 수월하다.
- 하위 요소를 자유롭게 추가하고 삭제할 수 있다.
🧼 이벤트 버블링에 대해 설명해주세요!
- 이벤트 버블링은 특정 요소에서 이벤트가 발생했을 때 해당 이벤트가 상위 요소들한테 차례로 전달되는 특성이다.
- event.propagation() 메소드로 이러한 버블링 현상을 막을 수 있지만, 잘 사용되지 않는다.
- 하위요소 → 상위요소로 이벤트가 전파되는 것은 이벤트 버블링이며, 이와 반대로 상위요소 → 하위요소로 이벤트가 전파되는 것은 이벤트 캡처링이다.
- 이러한 이벤트 버블링, 캡쳐링 특성을 이용하여 하위요소마다 이벤트를 등록하지 않아도 공통된 상위요소에 이벤트를 등록해 관리할 수 있는 패턴을 이벤트 위임이라고 한다.
이 글은 아래의 글을 바탕으로 공부하며 개인적으로 정리한 글입니다.
이미지에 대한 출처는 모두 아래에 있는 포스팅에 있습니다.