stopPropagation 과 preventDefault 차이는 뭘까??

HarryFront·2021년 3월 23일
6

비슷하지만 다른 event.stopPropagation과 preventDefault!

사실 처음 stopPropagation을 만나보았을때 '오호라 이런게 있었어???'라고 생각했다...ㅠㅠ
우선 stopPropagation을 알려면 HTML 상에서 사용자 이벤트가 어떻게 전달되는지 이해 해야한다.

html 상에서의 사용자 이벤트 전달 방식

우리가 마우스로 어떠한 태그(ex. div, ul, li, a 등)를 클릭했을 경우 많은 분들이 해당 태그만 클릭이 되었다고 생각하는 경우가 많다.
하지만 해당 태그만이 클릭 이벤트를 감지하는 것이 아니라 태그를 감싸고 있는 부모 태그들도 클릭 이벤트를 인식하고 반응하게 된다.
이것을 버블업(Bubble Up) 또는 버블링(Bubbling)이라고 한다.

[출처] https://joshua1988.github.io/web-development/javascript/event-propagation-delegation/

위 그림에서 보는 것 처럼 최하위 태그(요소)의 div를 클릭 했을때 그 상위 태그(요소)에 이벤트가 감지되고 그 다음의 상위요소가 감지 순차적으로 상위요소들이 클릭 이벤트를 감지하게 된다.

event.stopPropagation() 란?

이러한 버블링 또는 버블업을 막는 것이 stopPropagation이라고 보면 된다.

예를 들어

<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8" />
    <meta http-equiv="X-UA-Compatible" content="IE=edge" />
    <meta
      name="viewport"
      content="viewport-fit=cover, user-scalable=no, width=device-width, initial-scale=1, maximum-scale=1"
    />
    <title>예제1</title>
  </head>
  <body>
    <div>
      <div class="div-button">날 눌러보소</div>
    </div>
  </body>
  <script>
    document.querySelector(".div-button").addEventListener("click", () => {
      alert(".div-button 클릭!");
    });

    document.body.addEventListener("click", () => {
      alert("body 클릭!");
    });
  </script>
</html>

이 소스를 실행하여 '날 눌러보소' 라는 텍스트를 클릭해보면 두번에 alert가 실행되는 것을 볼 수 있다.

그렇다면 stopPropagation 을 추가할 경우를 한번 실행해보도록 하자!

<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8" />
    <meta http-equiv="X-UA-Compatible" content="IE=edge" />
    <meta
      name="viewport"
      content="viewport-fit=cover, user-scalable=no, width=device-width, initial-scale=1, maximum-scale=1"
    />
    <title>예제1</title>
  </head>
  <body>
    <div>
      <div class="div-button">날 눌러보소</div>
    </div>
  </body>
  <script>
    document.querySelector(".div-button").addEventListener("click", (e) => {
      e.stopPropagation();
      alert(".div-button 클릭!");
    });

    document.body.addEventListener("click", (e) => {
      alert("body 클릭!");
    });
  </script>
</html>

단순히 '.div-button'의 클릭을 감지하는 이벤트 리스너에 e.stopPropagation()을 추가 해준 것뿐인데 이번엔 alert창이 한번만 뜨는 것을 확인할 수 있다.

이렇게 상위요소로 해당 이벤트를 전달하지 않고 자신만 이벤트를 감지하도록 사용하는 것이 stopPropagation 이다.

event.preventDefault() 란 무엇일까?

아마 사실 이 preventDefault 는 어느정도 웹개발을 해보신 분들은 대부분 알고 있을 것이라 생각한다.
그치만! 한번 더 간단하게 상기해본다라고 스스로 생각하고 정리를 해보도록 하겠다!!! (사실 나도 좀 모지리라....ㅠㅠ)

preventDefault 는 기본으로 정의된 이벤트를 작동하지 못하게 하는 메서드 라고 정의를 내릴 수 있다.
이 preventDefault를 설명할때 가장 많이 나오는 예제가 있다! 소스를 보면서 살펴보도록 하자!!

<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8" />
    <meta http-equiv="X-UA-Compatible" content="IE=edge" />
    <meta
      name="viewport"
      content="viewport-fit=cover, user-scalable=no, width=device-width, initial-scale=1, maximum-scale=1"
    />
    <title>예제2</title>
  </head>
  <body>
    <div>
      <a href="https://naver.com" id="naver-link">네이버로 이동</a>
    </div>
  </body>
  <script>
    document.querySelector("#naver-link").addEventListener("click", (e) => {
      alert("네이버로 이동하잣!!! Harry 가잣!!!");
    });
  </script>
</html>

이 소스를 실행해 본다면 '네이버로 이동하잣!!! Harry 가잣!!!' 이라는 alert창이 먼저 나온뒤 곧바로 페이지가 네이버 페이지로 이동하게 될 것이다.
하지만 난 페이지 이동을 하지 않고 alert 메세지만 띄워주고 싶다고 가정을 해보자! 그렇다면 페이지 이동은 나에게 있어서 방해가 되는 요소가 될 것이다.
물론 'href="#"이라고 하면 페이지 이동을 안할 수 있지 않은가?'라고도 할 수 있지만 이것은 그냥 예제이니...
이럴 때 쓰는 것이 preventDefault이다. 그럼 preventDefault를 써서 페이지 이동을 하지 않게 하면서 alert창만 띄워줘보도록 해보자

<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8" />
    <meta http-equiv="X-UA-Compatible" content="IE=edge" />
    <meta
      name="viewport"
      content="viewport-fit=cover, user-scalable=no, width=device-width, initial-scale=1, maximum-scale=1"
    />
    <title>예제2</title>
  </head>
  <body>
    <div>
      <a href="https://naver.com" id="naver-link">네이버로 이동</a>
    </div>
  </body>
  <script>
    document.querySelector("#naver-link").addEventListener("click", (e) => {
      e.preventDefault(); //preventDefault 추가!
      alert("네이버로 이동하잣!!! Harry 가잣!!!");
    });
  </script>
</html>

소스를 실행해보면 더 이상 페이지 이동을 하지 않고 alert 메세지만 띄워주는 것을 볼 수 있을 것이다.

결론

  1. event.stopPropagation() 는 상위 요소가 이벤트를 감지할 수 없고 이벤트리스너가 가르키고 있는 요소만 이벤트를 감지한다.
  2. event.preventDefault() 는 등록되어 있는 이벤트 말고는 다른 이벤트를 작동하지 못하게 한다.

P.S : 잘못된 정보나 부분이 있다면 언제든지 피드백 주시기 바라겠습니다.
저도 스스로 다시 정리하기 위해 정리를 해놓는 거라 피드백 감사히 기쁜 마음으로 받겠습니다 ^^

profile
기획자 같지만 개발자 같게 개발자 같지만 디자이너 같게

1개의 댓글

comment-user-thumbnail
2023년 7월 11일

잘보고 갑니다^^

답글 달기