오늘은 이벤트의 버블링, 캡쳐링, 위임에 대해서 알아보는 시간을 갖겠어용~!
위 이미지는 이벤트가 일어나는 과정을 간략하게 그려놓은 흐름도 입니다.
표준 DOM이벤트에서 정의한 이벤트 흐름에는 총 3가지 단계가 있어요.
1. 캡쳐링 단계 : 이벤트가 하위 요소로 전파되는 단계
2. 타깃 단계 : 이벤트가 실제 타깃요소에 전달되는 단계
3. 버블링 단계 : 이벤트가 상위 요소로 전파되는 단계
캡처링은 최상위 요소에서 이벤트가 발생한 요소를 찾아가는 것을 말한다.
잘 사용되지 않는다고 한다.
// 사용예제
// div 까지의 캡쳐링
const input = document.querySelector("div");
const clickEvent = (e) => {
cosole.log(e.currentTarget.tagname);
};
input.addEventListener("click", clickEvent, {capture: true});
on<event>
프로퍼티나 HTML 속성, addEventListener
의 capture
옵션의 값이 true면 캡쳐링일 때 동작하게 할 수 있다.
반대로 옵션의 값이 false면 버블링 일 때 동작.
한 요소에서 이벤트가 발생하면 이 요소에 할당된 이벤트 핸들러가 동작하고 이후 부모요소의 핸들러가 동작한다, 그렇게 최상단 요소까지 타고 올라가면서 이벤트 핸들러가 동작한다.
버블 버블 버블 팝 버블 버블 팝 팝
// 사용 예제
// 누른 요소에 대한 alert
<form onclick="alert('form')">FORM
<div onclick="alert('div')">DIV
<p onclick="alert('p')">P</p>
</div>
</form>
p태그를 클릭하면 p -> div -> form 순으로 alert가 출력된다.
버블링은 거의
모든 동작에서 일어나는데 어떻게 막나요?
<body onclick="alert(`버블링은 여기까지 도달하지 못합니다.`)">
<button onclick="event.stopPropagation()">클릭해 주세요.</button>
</body>
.stopPropagation();
이거쓰면 위로 버블링 되는건 막아주는데 같은 레벨에서 동작하는 이벤트들은 못 막음
event.stopImmediatePropagation()
이렇게 하면 같은 레벨에서 동작하는 이벤트도 막아줌
이벤트 중에서는 버블링이 안되는 이벤트들이 있다.
마우스이벤트
포커스 이벤트
event.target과 event.currentTarget의 차이를 아는 것도 중요하다.
event.target : 이벤트가 발생한 요소 (고정)
event.currentTarget : 현재 실행중인 이벤트가 할당된 요소 (변경됨, this)
예를 들어 위에 이미지의 input에서 동작이 일어났으면 target은 input이 되고 currentTarget은 이벤트 리스너가 달린 다른 태그가 될 수 있다.
버블링의 속성을 이용하여 이벤트 위임이라는 것을 할 수 있다.
이벤트 위임이란?
원하는 요소 그룹의 부모에 이벤트를 할당하여 자식그룹에 동일한 이벤트를 사용하게 하는 것이다.
표나 같은 형식의 인풋이나 요소를 클릭하는곳에 사용할 수 있다.
<button data-toggle-id="subscribe-mail">
구독 폼 보여주기
</button>
<form id="subscribe-mail" hidden>
메일 주소: <input type="email">
</form>
<script>
document.addEventListener('click', function(event) {
let id = event.target.dataset.toggleId;
if (!id) return;
let elem = document.getElementById(id);
elem.hidden = !elem.hidden;
});
</script>
이런 식으로 사용이 된다.
https://ko.javascript.info/bubbling-and-capturing
https://ko.javascript.info/event-delegation