본문 바로가기

Web/JavaScript

브라우저 기본 동작

728x90

 

상당수의 이벤트에는 브라우저에 의한 특정 동작을 자동 수행한다

 

예시

a > href 해당 URL 이동

submit > from 전송

 

 

기본 동작 막기

1. event 객체에서 event.preventDefault() > on<event> 가 아닌 경우는 다 무시됨 true든 return이든 다 안됨

2. on<event> 에서 false 반환

 

<a href="/" onclick="return false">false반환</a>
<a href="/" onclick="event.preventDefault()">preventDefault</a>

 

동작을 막은 후 다른 함수 실행

menu.onclick = function(event) {
  if (event.target.nodeName != 'A') return;

  let href = event.target.getAttribute('href');
  alert( href ); // 서버에서 데이터를 읽어오거나, UI를 새로 만든다거나 하는 등의 작업이 여기에 들어갑니다.

  return false; // 브라우저 동작을 취소합니다(URL로 넘어가지 않음).
};

 

 

 

passive옵션 사용하기

 

addEventListener의 passive: true 옵션은 브라우저에게 preventDefault()를 호출하지 않겠다고 알리는 역할이다.

모바일 기기에는 사용자가 스크린에 손가락을 대고 움직일 때 발생하는 touchmove와 같은 이벤트가 있다.

이런 이벤트는 기본적으로 스크롤링(scrolling)을 발생시킨다. 핸들러의 preventDefault()를 사용하면 스크롤링을 막을 수 있다.

브라우저는 스크롤링을 발생시키는 이벤트를 감지했을 때 먼저 모든 핸들러를 처리하는데, 이때 preventDefault가 어디에서도 호출되지 않았다고 판단되면, 그제야 스크롤링을 진행한다. 이 과정에서 불필요한 지연이 생기고, 화면이 ‘덜덜 떨리는’ 현상이 발생한다.

passive: true 옵션은 핸들러가 스크롤링을 취소하지 않을 것이라는 정보를 브라우저에게 알려주는 역할을 한다. 이 정보를 바탕으로 브라우저는 화면을 최대한 자연스럽게 스크롤링 할 수 있게 하고 이벤트는 적절하게 처리된다.

Firefox, Chrome 같은 몇몇 브라우저에서 touchstart 와 touchmove 이벤트의 passive 는 기본값이 true이다.

 

 

event.defaultPrevented

 

오른쪽 마우스 클릭시 contextmenu 이벤트가 발생된다

이 contextmenu 를 발생하지 않게 하고 다른 함수를 실행시킬 수 있다

<script>
  elem.oncontextmenu = function(event) {
    event.preventDefault();
    alert("버튼 컨텍스트 메뉴");
  };

  document.oncontextmenu = function(event) {
    event.preventDefault();
    alert("문서 컨텍스트 메뉴");
  };
</script>

 

그런데 이렇게 구현 했을 경우에 이벤트 버블링으로 인해 두개가 동시에 뜨게 된다

stopPropagation 을 사용한다면 버블링은 멈추겠지만 더이상 외부 코드를 이용해 코드 동작이 되지않는다.

 

 

이때 defaultPrevented 를 사용하여

기본 동작이 막혀 있을 경우 리턴시키는 방법을 쓰면 된다

 

 

아래는 이를 해결하는 코드

<p>문서 레벨 컨텍스트 메뉴(event.defaultPrevented를 확인함)</p>
<button id="elem">버튼 레벨 컨텍스트 메뉴</button>

<script>
  elem.oncontextmenu = function(event) {
    event.preventDefault();
    alert("버튼 컨텍스트 메뉴");
  };

  document.oncontextmenu = function(event) {
    if (event.defaultPrevented) return;

    event.preventDefault();
    alert("문서 컨텍스트 메뉴");
  };
</script>

 

 

 

stopPropagation 과 preventDefault 는 연곤이 없는 명백히 다른 메소드이다.

 

 

 

 

(정리)

각 이벤트에 대응하는 브라우저 기본 동작은 다음과 같습니다.

  • mousedown – 마우스가 움직인 곳에서 선택을 시작.
  • <input type="checkbox">를 click – input을 선택/선택해제.
  • submit – 폼 안에서 <input type="submit">을 클릭하거나 를 누르면 이 이벤트가 발생하고, 브라우저는 폼을 서버로 전송.
  • Enter
  • keydown – 키를 누르면 텍스트 박스에 글자를 추가하거나 그 외의 다른 동작을 수행.
  • contextmenu – 마우스 오른쪽 버튼을 클릭하면 발생하는 이벤트로, 브라우저 컨텍스트 메뉴를 보여줌.
  • 이 외의 다양한 기본 동작이 있음.

자바스크립트를 사용하면 기본동작을 명시적으로 막을 수 있다.

event.preventDefault()나 return false를 사용하면 이벤트를 막을 수 있다. return false를 사용하는 방법은 on<event>를 통해 할당한 핸들러에서만 동작한다.

addEventListener의 passive: true 옵션은 브라우저에게 기본동작을 막지 않을 것이라는 정보를 전달한다. 이 옵션은 모바일에서 발생하는 touchstart와 touchmove를 다룰 때 유용하다. 브라우저는 모든 핸들러를 처리하지 않아도 스크롤링을 시작할 수 있기 때문이다.

기본동작을 막은 경우, event.defaultPrevented 값은 true이고, 그렇지 않은 경우는 false.

 

 

 

 

기본동작 막기는 남용해서는 안됨!!

728x90