이벤트 버블링, 캡쳐링, 위임

이진우·2024년 1월 28일
0

코드잇 프론트엔드

목록 보기
8/11

오늘은 이벤트의 버블링, 캡쳐링, 위임에 대해서 알아보는 시간을 갖겠어용~!


위 이미지는 이벤트가 일어나는 과정을 간략하게 그려놓은 흐름도 입니다.

이벤트의 흐름

표준 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 속성, addEventListenercapture옵션의 값이 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()

이렇게 하면 같은 레벨에서 동작하는 이벤트도 막아줌

버블링 안되는 이벤트

이벤트 중에서는 버블링이 안되는 이벤트들이 있다.
마우스이벤트

  • mouseenter : 마우스 포인터가 요소 위로 올라온 순간
  • mouseleave : 마우스 포인터가 요소에서 벗어나는 순간

포커스 이벤트

  • focus : 요소에 포커스가 되는 순간
  • blur : 요소로부터 포커스가 빠져나가는 순간

event.target

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

profile
츄라이츄라이

0개의 댓글