[JS] 브라우저 기본 이벤트와 버블링,캡쳐링 방지

Kyle·2020년 11월 22일
4

web

목록 보기
4/5

기본 브라우저 이벤트 혹은 이벤트 전파 방지하기

브라우저의 기본 이벤트 혹은 버블링의 현상을 방지하고 싶은 상황이 있습니다. 이를 방지하기 위한 방법도 여러가지 입니다.

다만, 상황에 맞는 방법을 사용해야지 추후에 다른 문제점이 발생하지 않을 것 입니다. 브라우저 기본 이벤트부터 알아보고 그에 맞는 동작을 막는 법을 알아봅시다.

기본 동작 막기

브러우저의 기본 태그들은 기본 이벤트를 갖고 있는 경우가 많습니다. 예로 <a>태그는 클릭시 해당 URL로 이동하고 <form>submit시 서버에 폼이 전달돼 새로고침이 됩니다.

이러한 기본 브라우저의 이벤트를 방지하기 위한 방법이 있습니다.

  1. event.preventDefault()
  2. return false

위의 두 가지 방법도 다른 상황에서만 적용 가능하다.

1. event.preventDefault()

콜백함수에 event.preventDefault()을 사용하면 브라우저의 기본 동작을 막을 수 있다. event.preventDefault()을 통해서 기본동작을 멈춘 상태에서 event.defaultPrevented의 값은 true된다. 이것을 이용해서 추가적인 조건도 걸어줄 수있다.

2. return false

return falseonclick과 같은 on[event]로 이벤트를 걸어준 경우에만 사용할 수 있다. document.onclick=콜백함수 와 같이 작성된 경우 return false 해주면 기본 동작을 멈출 수 있다. 하지만 html 태그에서 on[event]속성을 이용해 이벤트를 생성해 준다면, 콜백함수에 return false로 동작이 멈추질 않는다.

<a href="https://www.naver.com" onclick="handleClick()">네이버 </a>
function handleClick() {
  console.log("event 막기");
  return false;
}

위의 코드와 같이 작성했을 때 브라우저는 아래와 같이 동작한다고 한다.

function(event) {
  handleClick()
}

그러므로 handleClick에서 반환한 값은 어디에도 사용되지 않기 때문에 동작하지 않는다고한다. 즉 return을 콜백함수에서 사용하고 싶다면, html태그에서 콜백함수를 호출한것을 반환해 주어야한다.

<a href="https://www.naver.com" onclick="return handleClick()">네이버 </a>

이벤트 전파 방지하기

  1. event.stopPropagation()
  2. event.preventDefault() / event.defaultPrevented

이벤트 전파를 방지하는 방법은 대표적으로 event.stopPropagation()이 있습니다. 말 그대로 propagation(전파)를 stop하는 것이다.

이벤트 전파를 멈추고 싶은곳에 event.stopPropagation()를 작성해주면 됩니다.

event.stopPropagation() 예시

아래의 코드펜의 2개의 예시를 실행해보고 파악해보자

  • event.stopPropagation()를 안했을 경우 :

  • event.stopPropagation()가 적용될 때 : capuring phase에서 event propagation이 막혔기 때문에 그 이후의 이벤트가 발생하지 않는다.

위의 예시를 보고 이해가 잘되지 않는다면 이벤트 전파 캡쳐링,버블링을 보고 이벤트 전파과정을 다시 이해해보자.

event.stopPropagation()의 위험한 점

이벤트 전파를 막는 경우는 흔하지 않을 뿐더러 막게 된다면 event.stopPropagation()이 작성된 후, 상위 또는 하위 있는 event는 죽은영역 (deadzone)이 된다고 합니다. event.stopPropagation()을 사용하면 위험한 시나리오가 모던 자바스크립트에 자세히 작성돼 있다. 간단히 하면 document단에서 모든 click 이벤트를 감지하고 싶은데 stopPropagation에 의해 deadzone이 되면 감지를 못한다.

위의 경우처럼 event.stopPropagation()의 문제를 event.preventDefault()event.defaultPrevented를 이용해 해결할 수 있다.

아래와 같이 작성한다면, a태그 위에서 우클릭을 할 때는 a클릭의 콜백함수만 동작하게 된다.

event.defaultPrevented의 값을 이용해서 이벤트 전파를 발생하고 싶은 경우와 아닌 경우를 구분할 수 있게 된것이다.

먼저 이벤트가 발생한 곳에 event.preventDefault()가 실행된다면 event.defaultPrevented값이 true로 변경된다는 점을 이용한다.

const a = document.querySelector("a");
a.addEventListener("contextmenu", handler);
document.addEventListener("contextmenu", documentContext);
function handler(event) {
  event.preventDefault(); // event.defaultPrevented값이 true가 된다.
  console.log("click handler");
}

function documentContext(event) {
  if (event.defaultPrevented) return; // event.preventDefault()가 발생됐기 때문에 true가 됐다.
  else {
    event.preventDefault();
    console.log(event.defaultPrevented);
    console.log("document");
  }
}

마무리

이벤트에 대해 조금이나마 알아보았는데 DOM Node와 관련된 메소드들도 많이 있는것 같다. 이번에 공부하면서 처음본 contains, getAttribute, data-OOO 등 유용한 속성과 메소드들을 뭘 만들어볼 때 찾아서 사용해보면서 익혀야 할 것 같다.

참조 : https://ko.javascript.info/bubbling-and-capturing

https://ko.javascript.info/default-browser-action

profile
Kyle 발전기

2개의 댓글

comment-user-thumbnail
2021년 5월 25일

👍

1개의 답글