[JS] e.preventDefault() vs stopPropagation()

이나현·2022년 3월 4일
0

JavaScript

목록 보기
13/13
post-thumbnail

오라운드 서비스에서는 메인에서 slider부분에 scroll을 사용한 swipe 기능이 주를 이룬다.

embla-carousel을 사용해서 해당 기능을 만들었다.

<문제사항>

이때, 발생하는 문제점은 마우스로 해당 슬라이드를 클릭한 뒤 swipe를 하려고 할 때, 각 상품에 매칭되어 있는 click 이벤트가 같이 발생되는 것이었다.
슬라이드 swipe가 진행된 뒤, 기 발생된 click 이벤트로 모달이나 페이지 이동이 이루어졌다.

해당 오류는 메인 페이지에서 사용자가 처음 접하는 부분에서 발생하는 오류이기 때문에 수정이 급하다고 생각하였다.

embla-carousel이 공동으로 사용되기 때문에 컴포넌트로 쪼개져 있었고, 해당 컴포넌트에서 event를 중단시키는 방법을 고안해 내었다.

<고려사항>

embla-carousel 컴포넌트에 children이 상속되어 있었기 때문에
1. embla-carousel 컴포넌트가 부모이다.
2. children이 자식이다.

이 두가지를 생각했어야 했다.

자식인 {children}에 onclick 이벤트가 있었고, 이를 제어하기 위해서 slide에서 scroll(swipe)기능이 진행될 때에 onclick 이벤트를 방지하는 함수가 필요했다.

    function handleClickDisable(event?: Event) {
      event?.stopPropagation();
      embla?.rootNode().removeEventListener('click', handleClickDisable);
    }
    if (startPosition !== endPosition) {
      embla?.rootNode().addEventListener('click', handleClickDisable);
    } else {
      embla?.rootNode().removeEventListener('click', handleClickDisable);
    }
  }, [endPosition]);

위의 방식으로 click 이벤트를 제어하는 방식을 사용했는데, 이때에 헷갈리는 부분이 생겼다.

event.preventDefault()와 event.stopPropagation()

이 두가지에서 고민을 했는데, 신기하게도 자주 사용하는 e.preventDefault()에서는 해당 이벤트가 제어되지 않고, e.stopPropagation()에서는 이벤트가 제어되는 것을 알 수 있었다.

이는 내가 아직 event 제어 방법에서 제대로된 차이를 잘 모르기 때문에 생긴 이해 부족이랄까(데헷.. 아직 주니어니까 이렇게 알아가는거로 하자 )

1. e.preventDefault()

[mdn e.preventDefault()]
mdn을 봤을 때, e.preventDefault()에 대한 설명은 다음과 같다.

Event 인터페이스의 preventDefault() 메서드는 어떤 이벤트를 명시적으로 처리하지 않은 경우, 해당 이벤트에 대한 사용자 에이전트(=브라우저)의 기본 동작을 실행하지 않도록 지정합니다.
preventDefault()를 호출한 이벤트도 수신기 중 하나에서 stopPropagation() 또는 stopImmediatePropagation()을 호출하기 전까지는 다른 이벤트와 마찬가지로 전파됩니다.

이는 a 태그로 쉽게 이해할 수 있다.
html에서 a 태그나 submit 태그는 고유의 동작이 있다.
a 태그는 1. onclick 이벤트 2. 페이지 이동 이 두가지 행동을 하게 된다.

이때 <a href="#"/>을 하게 되면 click이벤트만 발생되고, 브라우저 이동은 하지 않는다. 대신, 클릭을 할 때에 페이지가 위로 이동하게 되는데, 이런 기본적인 브라우저의 행동을 막기 위해 사용하는 것이 e.preventDefault()이다.

추가로, a 태그의 클릭이벤트를 e.preventDefault() 할 경우, href 속성이 중단된다.

$("a").click(function(e){
	e.preventDefault();
	alert("e.preventDefault()");
});

2. e.stopPropagation()

[mdn e.stopPropagation()]

이번에는 e.stopPropagation에 대한 공식문서의 내용을 보도록 하겠다.

Event 인터페이스의 stopPropagation() 메서드는 현재 이벤트가 캡처링/버블링 단계에서 더 이상 전파되지 않도록 방지합니다.
전파를 방지해도 이벤트의 기본 동작은 실행되므로, stopPropagation()이 링크나 버튼의 클릭을 막는 것은 아닙니다.
이런 기본 동작을 방지하려면 preventDefault() 메서드를 사용하세요. 또한, stopPropagation()은 같은 이벤트 대상에 부착한 다른 수신기까지 막지는 않습니다.
이것까지 막으려면 stopImmediatePropagation()를 사용하세요.

e.stopPropagation()의 공식문서를 보면, 좀 더 명확하게 이해할 수 있는 것 같다.
이벤트의 전파를 막기위해서는 e.stopPropagation()을, 기본 브라우저의 동작을 막기 위해서는 e.preventDefault()를 사용해야한다.

해당 내용은 https://pa-pico.tistory.com/20 에서 너무 잘 설명해 두었기 때문에 사이트를 참고하는 것이 좋다.

결론

결국, 고려사항을 고려해 보았을 때, e.stopPropagation()이 맞는 이벤트 방지 구문이었다.
두 개의 다른 이벤트가 한 slide 안에서 이뤄지는 것이고 부모 - 자식간의 버블링 현상이 있었으므로, 이 버블링을 막기 위해서 e.stopPropagation()을 사용해야만 원하는 기능이 작동되었다.

마구잡이로 쓰던 e.preventDefault()에 대해 정리해보고, e.stopPropagation()까지 배우고 정리해볼 수 있는 시간이다. 굿!

[참고사이트]
1. mdn

  1. https://ismydream.tistory.com/98
  2. https://pa-pico.tistory.com/20
profile
technology blog

0개의 댓글