상세 컨텐츠

본문 제목

[Javascript] 25. Event Capture, Propagation, Bubbling and Once

Experience/[Javascript] JS 30

by winCow 2021. 5. 8. 15:30

본문

1. 개요

이벤트 캡처링과 버블링과 이를 중단하는 방법, 이벤트에 한 번만 반응하는 방법이다.

 

 

2. HTML

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>Understanding JavaScript's Capture</title>
</head>
<body class="bod">

  <div class="one">one
    <div class="two">two
      <div class="three">three
      </div>
    </div>
  </div>
  
  <button>button</button>
  
</body>
</html>

 

 

3. CSS

  html {
    box-sizing: border-box;
  }
  
  *, *:before, *:after { 
    box-sizing: inherit; 
  }

  div {
    width: 100%;
    padding: 100px;
  }

  .one {
    background: thistle;
  }

  .two {
    background: mistyrose;
  }

  .three {
    background: coral;
  }

 

 

4. Javascrip

  const divs = document.querySelectorAll('div');

  function logText(e) {
    console.log(this.classList.value);
  }

  document.body.addEventListener('click', logText);
  divs.forEach(div => div.addEventListener('click', logText));

이벤트 버블링은 자식 요소에 이벤트가 전달되었을 때, 부모 요소에도 이벤트가 같이 전달되는 것이다. 위 코드와 같이 모든 div에 클릭 이벤트 리스너를 걸어 logText 함수를 실행시키도록 하는데, logText는 콘솔 창에 클래스 명을 출력하는 함수이다. 가장 바깥의 큰 사각형이 one, 두 번째 사각형이 two, 가장 작은 사각형이 three인데, 가장 작은 사각형인 three를 클릭하면 three > two > one 순으로 출력된다. 즉, 안쪽의 자식 요소가 클릭되면 조상 요소까지 전부 이벤트를 받는 것이다. one의 조상인 body에 클래스명을 입력하면 이것 역시 one 뒤에 출력된다.

 

  function logText(e) {
    console.log(this.classList.value);
    e.stopPropagation();
  }

  divs.forEach(div => div.addEventListener('click', logText));

여기에 stopPropagation 매소드를 입력하면 이벤트 버블링을 제어할 수 있다. 위 코드를 적용하여 요소들을 클릭하면, 실제로 클릭된 요소에만 이벤트가 전달된다.

 

  function logText(e) {
    console.log(this.classList.value);
  }

  divs.forEach(div => div.addEventListener('click', logText, {
    capture: true
  }));

이벤트 버블링과는 반대로, 부모 요소에서 자식 요소로 이벤트가 전파되는 것을 이벤트 캡쳐링이라고 한다. 이벤트를 전달할 때 capture: true를 설정하면(default는 false) 이벤트 버블링 대신 캡쳐링이 발생한다. 이 경우에는 three를 클릭하면 조상 요소인 one부터 선택되어 콘솔창에는 one > two > three 순으로 출력된다. 

 

  const button = document.querySelector('button');


  button.addEventListener('click', () => {
    console.log('click!!');
  }, {
    once: true
  });

이벤트를 전달할 때 사용할 수 있는 다른 옵션으로는 once가 있다. 이는 해당 이벤트가 단 한 번만 발생하게 한다. 위의 버튼은 아무리 클릭해도 콘솔 창의 click!! 문자열은 단 한 번만 출력된다.

관련글 더보기

댓글 영역