개발자 Saaad

[JavaScript] 이벤트 버블링 (Event Bubbling) 본문

학습/kakao X goorm 풀스택12회차

[JavaScript] 이벤트 버블링 (Event Bubbling)

Saaad 2024. 11. 27. 18:15

Event Bubbling

이벤트 버블링이란 아래 그림에서처럼 가장 깊게 중첩 된 요소(3)에 이벤트가 발생했을 때

이벤트가 위로 (bubble up) 전달되는 것을 의미합니다.

그래서 3번 요소, 2번 요소, 1번 요소에 그 이벤트에 대한 핸들러가 있다면 3번 요소의 핸들러가

실행되고 2번,1번 순서로 실행됩니다.

버블링 설명

 

 


Bubbling 예제

버블링의 원리는 간단합니다. 

한 요소에 이벤트가 발생하면, 이 요소에 할당된 핸들러가 동작하고, 이어서 부모 요소의 핸들러가 동작합니다. 

가장 최상단의 조상 요소를 만날때까지 이 과정이 반복되면서 핸들러가 동작합니다.

 

3개의 요소가 FORM > DIV > P 형태로 중첩된 구조를 살펴봅시다. 

요소 각각에 핸들러가 할당되어 있습니다

<!doctype html>
<body>
<style>
  body * {
    margin: 10px;
    border: 1px solid blue;
  }
</style>

<form onclick="alert('form')">FORM
  <div onclick="alert('div')">DIV
    <p onclick="alert('p')">P</p>
  </div>
</form>
</body>

실행 화면

가장 안쪽의 <p> 를 클릭하면 순서대로 다음과 같은 일이 벌어집니다.

1. <p>에 할당된 onclick 핸들러 동작

2. 바깥의 <div> 에 할당된 핸들러 동작

3. 바깥의 <form> 에 할당된 핸들러 동작

4. document 객체를 만날 때까지, 각 요소에 할당된 onclick 핸들러가 동작

 

버블링 설명 그림

이런 동작 방식 때문에 <p> 요소를 클릭하면 p > div > form 순서로 3개의 alert 메시지창이 뜨는 것을 알 수 있습니다.

 


event.target

부모 요소의 핸들러는 이벤트가 정확히 어디서 발생했는지 등에 대한 자세한 정보를 얻을 수 있습니다.

이벤트가 발생한 가작 안쪽의 요소는 타깃(target) 요소라고 불리고, event.target 을 사용해 접근할 수 있습니다.

 

event.target 과 this (=event.currentTarget) 는 다음과 같은 차이점이 있습니다.

  • event.target 은 실제 이벤트가 시작된 '타깃' 요소입니다. 버블링이 진행되어도 변하지 않습니다.
  • this는 '현재' 요소로, 현재 실행 중인 핸들러가 할당된 요소를 참조합니다.

예시를 살펴봅시다. 핸들러는 form.onclick 하나 밖에 없지만 이 핸들러에서 폼 안의 모든 요소에서 발생하는 클릭 이벤트를

'잡아내고(catch)' 있습니다. 클릭 이벤트가 어디서 발생했든 상관없이 <form> 요소까지 이벤트가 버블링 되어 핸들러를 

실행시키기 때문입니다.

form.onclick 핸들러 내의 thisevent.target은 다음과 같습니다.

 

    • this(event.currentTarget) - <form> 요소에 있는 핸들러가 동작했기 때문에 <form>을 가리킵니다.
    • event.target - 폼 안쪽에서 실제 클릭한 요소를 가리킵니다.

HTML

<!DOCTYPE HTML>
<html>

<head>
  <meta charset="utf-8">
  <link rel="stylesheet" href="example.css">
</head>

<body>
  클릭하면 <code>event.target</code>과 <code>this</code>정보를 볼 수 있습니다.

  <form id="form">FORM
    <div>DIV
      <p>P</p>
    </div>
  </form>

  <script src="script.js"></script>
</body>
</html>

 

JS

form.onclick = function(event) {
  event.target.style.backgroundColor = 'yellow';

  // chrome needs some time to paint yellow
  setTimeout(() => {
    alert("target = " + event.target.tagName + ", this=" + this.tagName);
    event.target.style.backgroundColor = ''
  }, 0);
};

예제 사이트에 들어가면 볼 수 있는 화면. 직접 확인해보자

https://ko.javascript.info/article/bubbling-and-capturing/bubble-target/\

 

https://ko.javascript.info/article/bubbling-and-capturing/bubble-target/

 

ko.javascript.info

 

 

p 영역을 클릭했을때

 

div 영역을 클릭했을 때
form 영역을 클릭했을 때

위 결과를 보면 target은 정확히 사용자가 클릭한 지점에 있는 요소를 가리키고 있는 것을 확인할 수 있고, 

this는 form.onclick = function(event) {} 가 동작하는 것이기 때문에 핸들러의 주체인 form 을 가리키는 것을 알 수 있습니다.

 

버블링을 중단하고 싶다면

event.stopPropagation() 을 사용하면 됩니다.

<body onclick="alert(`버블링은 여기까지 도달하지 못합니다.`)">
  <button onclick="event.stopPropagation()">클릭해 주세요.</button>
</body>

아래 사이트에서 실행해볼 수 있습니다.

https://plnkr.co/edit/?p=preview&preview

 

Plunker

Plunker is loading… It's really nice to see you today!

plnkr.co