상당수의 이벤트에는 브라우저에 의한 특정 동작을 자동 수행한다
예시
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.
기본동작 막기는 남용해서는 안됨!!
'Web > JavaScript' 카테고리의 다른 글
브라우저 이벤트정리 2.Moving the mouse (0) | 2023.10.22 |
---|---|
브라우저 이벤트 정리 1. 마우스이벤트 (0) | 2023.10.22 |
이벤트 위임(event delegation) (1) | 2023.10.21 |
[Bubbling, Capturing] (1) | 2023.10.21 |
[browser event] 자주 이용하는 DOM 이벤트 (1) | 2023.10.20 |