preventDefault()

Seung·2022년 2월 18일
0

preventDefault() : 브라우저에서 기본적으로 발생하는 동작을 취소해준다.

아래 코드를 보면서 이해하자


😄 code 1.

/*HTML*/
<div>
	<input type="checkbox" />
</div>

/*JavaScript*/
const checkBox = document.querySelector('input');
checkBox.addEventListener('click', (event) => {
  	console.log('체크박스 선택했습니다');
	event.preventDefault();
});
  • 위의 코드를 실행해보면 checkbox를 클릭해도 클릭이 안되는 걸 볼 수가 있다. 반대로 console.log는 출력해준다.
    즉 preventDefault()는 사용자가 등록한 것을 취소하는게 아닌(console.log같은 것) 브라우저에서 기본적으로 등록된 걸 취소해주는 것을 알 수가 있다

  • 그럼 preventDefault()를 사용하면 모든 이벤트들의 브라우저에서 기본적으로 등록된 것들은 취소해줄까??
    아니다 아래 코드를 보자


😄 code 2.

/*HTML*/
<div></div>
<div></div>
<div></div>
<div></div>
<div></div>
<div></div>
<div></div>
<div></div>

/*CSS*/
div {
  width : 250px;
  height : 250px;
  background-color : black;
}

/*JavaScript*/
document.addEventListener('scroll', (event) => {
	console.log('스크롤');
    event.preventDefault();
});

document.addEventListener('wheel', (event) => {
	console.log('휠');
    event.preventDefault();
});
  • 위의 코드에서 addEventListener('scroll')를 실행하면 preventDefault()가 있음에도 불구하고 스크롤이 정상적으로 되는것을 볼 수가 있다

  • 두번째 코드인 addEventListener('wheel')을 실행해보면 wheel도 정상적으로 동작하지만 scroll과 반대로 console에 오류가 나오는 것을 확인할 수가 있다

대체 왜 ??

그 이유는 passive 때문이다. active는 능동적, passive는 수동적을 의미하는데
passive는 boollean 값으로 passive가 true일 때는 preventDefault()가 있어도 preventDefault()를 호출하지 않겠다는 것을 말하고 passive가 false일 때는 active로 preventDefault()가 있으면 호출하겠다는 것을 말한다

  • 참고로 passive는 addEventListener에서 3번째 인자값으로 줄 수 있다

  • 위 개념을 토대로 생각해보면 preventDefault()를 사용해서 브라우저의 기본 동작을 막겠다고 한다면 무조건 passive : false여야 한다

  • 그런데 code1.과 code2.에서는 눈을 씻고 봐도 passive를 찾아볼 수 없었는데 click은 중지됐고 scroll은 중지 안됐고 wheel은 중지 안됐지만 오류가 나오는 것을 확인했다

    왜 그럴까?

    이벤트마다 passive의 default 값이 다르기 때문이다.
    code1. 에서 click 이벤트는 passive의 default 값이 false로 passive를 생략해도 passive가 false이기 때문에 정상적으로 preventDefault()가 동작했다.
    하지만 code2.에서 scroll과 wheel은 passive의 default 값이 true로 preventDefault()를 호출하지 않은 것이다

  • scroll과 wheel에서 preventDefault()가 동작 안한 것은 알았지만 왜 wheel에서만 오류가 난 것일까?

    이유는 간단하다
    위에서 passive가 true일 때는 preventDefault()가 있어도 사용을 못하는데 code2.에서 wheel은 passive가 true인데 preventDefault()를 사용해서 오류가 난 것이다.

    근데 scroll은 오류가 안났는데...??
    그 이유는 scroll 이벤트는 기본적으로 취소 시킬 수 없는 이벤트이기 떄문이다.
    이게 무슨 말이냐면 각 이벤트들마다 preventDefault(), passive 관계 없이 취소 시킬 수 없는 이벤트들이 있다. 대표적으로 scroll 이벤트가 이에 해당되는데 scroll 이벤트는 무조건 취소 시킬 수 없기 때문에 preventDefault()가 있어도 오류를 출력 안한것이다. (어차피 취소 못시키 때문)
    이를 확인해보고 싶다면 scroll 이벤트 핸들러와 wheel 이벤트 핸들러에 각각 console.log(event.cancelable); (이벤트 취소시킬 수 있는지 여부)를 추가해보면 scroll은 false, wheel은 true가 나오는 것을 확인할 수 있다


✨ 결론 ✨

  • scroll과 같은 기본적으로 취소시킬 수 없는 이벤트는 preventDefault(), passive 사용해도 취소 못시킨다

  • wheel과 같은 passive의 default값이 true이면서 기본적으로 취소시킬 수 있는 이벤트는 passive를 false로 바꾸고 preventDefault()를 사용하면 취소시킬 수는 있지만 성능에는 무지막지하게 안좋다

  • click과 같은 passive의 default값이 false인 것들은 preventDefault()를 사용해서 취소 시킬 수 있다

  • 즉 click과 같이 active 한 것들은 preventDefault()를 잘 사용하면 성능이 좋아질 수 있지만 wheel과 같이 passive한 것을 강제로 active로 바꾼 뒤 preventDefault()를 사용하면 성능이 정말로 안좋아질 수 있기 때문에 주의할 필요가 있다


😍 코드 지적은 언제나 환영입니다. 읽어주셔서 감사합니다. 😍

profile
지적은 제 발전의 원동력입니다. 사소한 것이라도 지적해주세요 :)

0개의 댓글