본 포스팅은 여기에 올라온 게시글을 바탕으로 작성되었습니다.
파트와 카테고리 동일한 순서로 모든 내용을 소개하는 것이 아닌, 몰랐거나 새로운 내용 위주로 다시 정리하여 개인공부 목적으로 작성합니다.
중간중간 개인 판단 하에 필요하다고 생각될 시, 기존 내용에 추가로 보충되는 내용이 있을 수 있습니다.
포인터(Pointer
) 이벤트는 마우스를 비롯한 다양한 포인팅 처리를 다루기 위해 고안된 비교적 최신 스펙의 이벤트이다. 전통적인 PC의 경우에는 마우스를 통해 포인팅(= 클릭관련) 이벤트가 발생했지만, 시간이 흘러 스마트폰, 태블릿과 같은 다양한 기기가 등장함에 따라 마우스를 사용하지 않고 터치가 이루어지게 되었다. 포인터 이벤트는 이러한 다양한 기기에서 발생하는 터치 역시 처리하기 위해 고안되었다.
포인터 이벤트가 등장하기 까지의 간단한 역사의 흐름을 짚어보자.
예전에는 마우스 이벤트만 가지고서 대부분의 이벤트를 처리했다. 브라우저는 보통 PC 환경에서 가장 많이 운용되었기 때문이다. 그러나 점차 터치 스크린을 지원하는 스마트폰이나 태블릿과 같은 기기들이 등장하게 되면서 이들을 통해 발생되는 이벤트 역시 적절하게 처리할 필요가 생겼다. 이 디바이스에서도 기존 마우스 이벤트로 간단한 동작들은 동일하게 처리가 가능했으나, 터치 스크린에서만 가능한 여러 동작들은 기존 마우스 이벤트로는 커버할 수 없었다. 가령 마우스 이벤트로는 두 손가락으로 터치하는 멀티 터치는 처리가 불가했다.
때문에 터치 이벤트를 적절히 다루기 위해 touchstart
, touchend
, touchmove
와 같은 이벤트들이 도입되었다. 그러나 이들 역시 충분히 다양한 터치 기기들을 지원하기에는 부족한 점이 많았다. 예를 들어 갤럭시 탭 또는 아이패드에서 사용하는 스마트 펜슬 등의 스틸러스를 사용하는 경우엔 해당 기기 역시 제대로 인식해야하는 것이 필요했는데, 터치 이벤트는 이들에 대한 지원이 다소 부족했다. 또한 터치 이벤트는 고유한 속성을 가지고 있었기 때문에, PC 환경과 모바일 디바이스 환경 모두 각각 따로 구현해야 함은 개발의 생산성을 저하시키는 원인이 되기도 했다.
이러한 문제를 해결하기 위해 포인터 이벤트가 고안되었고 표준으로 지정되었다. 포인터 이벤트를 사용하면, 기존 PC의 마우스 이벤트를 비롯해 다양한 기기에서의 터치 이벤트 모두 포함하여 하나의 이벤트로 다룰 수 있다.
현재 지원하고 있는 포인터 이벤트는 Level 2
로 명시되어 있다. Level 3
도 존재하지만 호환성 문제로 아직 정식 채택되지 않았다.
대부분의 모던 브라우저는 포인터 이벤트를 지원한다. 익스플로러 10 또는 사파리 12 버전의 구식 브라우저의 경우엔 해당 이벤트를 지원하지 않기에 사용할 수 없다. 또는 폴리필을 적용해서 사용해야 한다.
만약 구식 브라우저의 환경을 고려하지 않아도 된다면 포인터 이벤트를 사용해서 기존 마우스 이벤트와 모바일 디바이스에서 발생하는 터치 이벤트까지 모두 편리하게 관리할 수 있다. 포인터 이벤트의 속성과 쓰임새에 대해 살펴보도록 하자.
포인터 이벤트는 대부분 기존 마우스 이벤트와 동일하다.
Pointer Event | Mouse Event |
---|---|
pointerdown | mousedown |
pointerup | mouseup |
pointermove | mousemove |
pointerover | mouseover |
pointerout | mouseout |
pointerenter | mouseenter |
pointerleave | mouseleave |
pointercancel | - |
gotpointercapture | - |
lostpointercapture | - |
위 표를 보면 기존 mouse<event>
대부분이 동일하게 pointer<event>
형식으로 존재하는 것을 볼 수 있다. 포인터 이벤트에는 추가적으로 3개의 이벤트가 더 존재하는데 이들에 대한 설명은 조금 있다 자세히 살펴보도록 하자. 이들 셋을 제외하면 기존 마우스 이벤트가 포인터 이벤트와 1:1 대응하기 때문에, 기존 마우스 이벤트를 포인트 이벤트로 변경해도 잘 동작함을 볼 수 있다.
포인터 이벤트는 clientX/Y
, target
과 같은 마우스 이벤트 프로퍼티를 동일하게 가지고 있다. 거기에 추가적으로 포인터 이벤트만 독자적으로 가지는 프로퍼티도 있다.
pointerId
: 포인터 이벤트를 발생시키는 포인터(마우스, 터치 등)의 고유 아이디 값으로 브라우저가 부여한다. 이를 통해 멀티 포인터 처리를 다룰 수 있다.
pointerType
: 포인터 이벤트가 발생한 디바이스의 타입을 가지고 있다. 문자열 형식이며 mouse
, pen
, touch
중에 하나의 값을 가진다.
isPrimary
: true/false
의 Boolean
값으로, 만약 이 값이 true
라면 첫 번째 터치에 의한 포인터 이벤트를 말한다. 멀티 포인터 이벤트를 처리할 때 주로 사용한다.
추가적으로 몇몇 포인터 이벤트의 경우에는 디바이스에서 발생한 터치에 대한 크기 또는 압력을 필요로 하는 경우가 있다. 포인터 이벤트는 이에 대한 프로퍼티도 지원하고 있다.
width
: 포인터 이벤트가 발생한 지점의 너비를 담고 있다. 가령 손가락으로 터치하는 경우, 터치하는 부분의 접점에 대한 너비를 가리킨다. 마우스와 같이 이 속성을 지원할 필요가 없는 경우엔 항상 1
로 지정된다.
height
: 포인터 이벤트가 발생한 지점의 높이를 담고 있다. 위 width
속성과 동일하며, 지원하지 않는 타입이라면 역시 1
로 지정된다.
pressure
: 포인터 이벤트가 발생했을 때의 압력값을 가지고 있다. 기기마다 해당 프로퍼티를 지원 여부가 모두 다르다. 전제조건으로 터치패드에서 압력의 값을 계산할 수 있어야 한다. 이 값은 0 - 1
의 범위를 가지고 만약 지원하지 않는 타입이라면 보통 0.5
또는 0
의 값을 가진다.
tangentialPressure
: 접점 부에 발생하는 포인터 이벤트의 압력을 다룬다. 보통 잘 쓰이지 않는다.
tiltX, tiltY, twist
: 펜과 같은 도구를 사용할 때 기울기에 따른 값일 계산해야할 때가 있는데, 그에 관련한 값을 지원한다.
해당 프로퍼티의 경우는 범용적인 경우엔 잘 사용하지 않는다. 정말 특수한 경우에 해당 프로퍼티에 접근하여 어떤 처리가 필요할 수 있다.
포인터 이벤트가 기존 마우스 이벤트에 비해 가장 두드러지는 부분은 바로 멀티 터치 역시 다룰 수 있다는 점이다. 기존 마우스 이벤트는 멀티 터치 여부를 지원할 수 없었기 때문에 스마트폰이나 태블릿에서 발생하는 터치 이벤트를 모두 처리할 수 없었다.
포인터 이벤트는 멀티 터치와 관련된 부분을 pointerId
와 isPrimary
프로퍼티를 통해 처리할 수 있다. 어떤 기기에서 멀티 터치가 발생했을 때 일어나는 일은 다음과 같다.
pointerdown
이벤트 발생isPrimary = true
pointerId
값 부여pointerdown
이벤트 발생isPrimary = false
pointerId
값 부여여기서 pointerId
는 매번 발생하는 터치에 대해 각각 고유한 값을 발급한다. 만약 사용자가 동시에 연달아 5번의 터치를 발생시킨다면, 5번의 pointerdown
이벤트가 발생함과 동시에 해당 이벤트에 각기 다른 pointerId
가 부여된다. 그리고 오직 첫 번째 터치에 대해서만 isPrimary
값이 true
로 유지된다.
이 값들을 가지고 멀티 터치에 대한 이벤트를 추적할 수 있다. 만약 사용자가 터치 이후 손가락을 떼는 등의 동작을 취하게 되면 pointermove
와 pointerup
과 같은 이벤트가 pointerdown
이벤트가 발생했을 때와 동일한 pointerId
로 발생하게 된다. 따라서 이 값을 체크하여 해당 이벤트가 어디서 몇 번째로 발생한 터치 이벤트인지 구분할 수 있다.
pointercancel
이벤트는 기존 마우스 이벤트에서는 찾아볼 수 없는 새로운 이벤트이다. 해당 이벤트는 현재 작동하고 있는 포인터 상호작용 도중에 어떠한 이유로 이를 중단시키는 동작이 발생했을 때 호출되는 이벤트이다. 이렇게 도중에 중단을 요구하는 사례는 다음과 같은 경우들이 있을 수 있다.
이전 챕터에서 마우스 이벤트로 구현한 드래그 앤 드롭 기능을 포인터 이벤트에 대입하여 pointercancel
에 대한 예시를 살펴보자. 일단 드래그 앤 드롭은 포인터 이벤트를 사용하면 다음과 같이 구현할 수 있다.
pointerdown
이벤트 발생pointermove
이벤트 발생dragstart
등...)하는데, 해당 동작이 발생하면 기존 포인터 이벤트의 움직임을 취소시키는 pointercancel
이벤트 발생pointermove
이벤트는 즉각 중단됨즉 브라우저 기본 동작이 포인터 이벤트를 하이재킹(hijaking
)하고 있기 때문에 도중에 pointercancel
이벤트가 발생됨을 알 수 있다. 앞에서도 그랬던 것 처럼 커스텀한 드래그 앤 드롭 기능을 포인터 이벤트만 사용해 구현하기 위해서는 이러한 브라우저 기본 동작을 막아주어야 한다.
그리고 추가적으로 포인터 이벤트에서는 터치를 지원하는 디바이스에서의 브라우저 액션 호환성을 위해 CSS 속성을 지정해야 한다. 즉 pointercancel
이벤트를 회피하기 위해서는 다음 두 가지 작업을 수행해야 한다.
ball.ondragstart = () => false
off
시켜주어야 한다.#ball { touch-action: none }
해당 처리를 마친다면 더 이상 pointercancel
이벤트가 호출되지 않는 것을 확인할 수 있다.
포인터 이벤트는 캡처링(capturing
)이라는 기능을 추가적으로 지원한다. 아이디어 자체는 매우 간단하지만 처음에는 마우스 이벤트와 비교해서 생각하면 낯설어 보일 수 있다. 캡처링 설정을 위해 사용하는 메서드는 다음과 같다.
elem.setPointerCapture(pointerId)
: 주어진 pointerId
를 가지고 elem
요소에 이벤트를 바인딩 시킨다. 호출 이후 동일한 pointerId
를 가진 모든 포인터 이벤트는 target
프로퍼티로 elem
요소를 가지게 된다.즉 해당 메서드는 동일 pointerId
값으로 발생하는 모든 포인터 이벤트에 대해 elem
요소를 리타겟(re-target
)하도록 바인딩한다. 이 바인딩은 다음의 경우 해제된다.
pointerup
또는 pointercancel
등이 호출되는 경우 자동으로 해제elem
요소가 document
에서 제거되는 경우 자동으로 해제elem.releasePointerCapture(pointerId)
를 호출하는 경우이러한 캡처링 기능은 언제 사용할 수 있을까? 만약 주어진 범위 내에서 특정 버튼을 통해 좌우로 왔다갔다 할 수 있는 input
이 주어진다고 생각해보자. 보통 이러한 기능을 slider
라고 부르며, 특정 버튼은 thumb
라고 지칭한다.
위 그림에서 파란색 영역이 thumb
가 된다. 마우스 이벤트로 드래그 앤 드롭을 구현해서 thumb
를 주어진 범위 내에서 자유자재로 이동시킬 수 있다. 그런데 이때 thumb
를 누른채로 범위를 벗어나서 드래그하는 경우엔 현재 마우스 커서를 기반으로 이벤트를 감지하기 때문에 이동이 불가능하다. 그러나 thumb
에 처음 발생한 이벤트를 계속 유지할 수 있다면, 범위를 벗어나 전체 document
내에 어디에서든 드래그 하더라도 계속 이동시킬 수 있을 것이다. 이처럼 첫 발생한 이벤트를 유지하도록 리-타겟팅하여 관리하고자 할 때 캡처링을 사용할 수 있다.
pointerdown
이벤트 핸들러 내부에서thumb.setPointerCapture(event.pointerId)
메서드를 호출하여 현재 이벤트를 캡처링한다.pointerId
로 발생하는 모든 이벤트는 위에서 캡처링된 이벤트를 계속 타겟팅한다. 이는 pointerup/cancel
이 호출되기 전까지 유효하다.pointerup
이벤트가 호출되면 캡처링은 자동으로 제거되기 때문에 후속작업에 대해 신경쓸 필요가 없다.이처럼 캡처링을 통해 이벤트를 유지시키면 간단하게 드래그 앤 드롭 기능을 효과적으로 사용할 수 있다. 첫 이벤트가 다음에 발생하는 이벤트와 정보를 공유하기 때문에 clientX/Y
와 같은 프로퍼티 값들도 정확하게 계산할 수 있는 이점이 있다.
추가적으로 이런 캡처링이 설정되고 해제되는 순간을 잡아낼 수 있는 이벤트가 있다. 이들이 각각 gotpointercapture
과 lostpointercapture
이다. 각각의 이벤트는 캡처링이 설정될 때, 그리고 해제될 때 호출된다.
React
에서도Pointer
이벤트를 지원한다.JSX
문법에 맞게onPointerDown
과 같은 속성으로 사용할 수 있다. 그러나 포인터 이벤트가 아직 모든 브라우저에서 지원되지 않는 이유로 폴리필을 포함해야 한다.react-dom
은 표준 폴리필이 번들을 무겁게 만들기 때문에 리액트가 직접 브라우저 호환성을 위해 폴리필을 제공하지는 않고 있다. 때문에 애플리케이션 포인터 이벤트를 의존한다면 직접 서드 파티 포인터 폴리필을 추가해야 한다.
키보드 관련 이벤트는 키보드를 통해 발생하는 이벤트를 다룬다. 그러나 해당 이벤트를 다루기 전에 짚고 넘어가야 할 점이 있다. 모던 브라우저에서 무언가를 입력하는 행위는 더 이상 키보드에 국한되지 않는다. 예를 들어 음성 인식 기술을 통해 일련의 컨텐츠가 입력될 수도 있으며, 단순하게는 마우스를 통해 복사/붙여넣기를 통해서도 입력을 받을 수 있다.
때문에 모던 브라우저에서는 <input>
필드에서 값을 입력하는 행위는 키보드 이벤트 외에도 다양한 이벤트로 처리할 수 있다. 때문에 보통 <input>
태그와 같이 입력값을 받는 요소에서는 키보드 이벤트로 한정하지 않고 onchange
이벤트와 같이 변화를 감지하는 방식을 통해 값을 입력받는 경우가 많다.
때문에 오늘날 키보드 이벤트의 활용은 그렇게 빈번하지 않다. 이번 챕터에서는 키보드를 눌렀을 때(keydown
)와 떼었을 때(keyup
) 발생하는 이벤트 위주로 관련 내용을 살펴보도록 하자.
keydown
이벤트는 키보드에서 어떤 키를 눌렀을 때 발생하고, keyup
은 해당 키가 다시 떼어지면 발생한다. 키보드 이벤트는 크게 code
와 key
라는 속성을 가지고 있다.
event.key
프로퍼티는 문자 자체에 대한 정보를 가지고 있고, event.code
프로퍼티는 물리적인 키의 코드값에 대한 정보를 가지고 있다.
예를 들어 z
키를 입력하는 경우를 생각해보자. 단순히 z
키만 누르는 경우와 Shift
와 함께 입력해 대문자 형태의 Z
키를 입력하는 경우를 생각해볼 수 있다. 이때 각 프로퍼티가 가지는 값은 다음과 같다.
Key | event.key | event.code |
---|---|---|
z | z(소문자) | KeyZ |
Shift + z | Z(대문자) | KeyZ |
소문자냐 대문자냐에 따라서 event.key
는 각각의 경우에 해당하는 문자 자체를 가리키는 것을 알 수 있다. 그러나 event.code
의 경우에는 이에 상관없이 항상 동일한 키 코드값을 가리키는 것을 볼 수 있다.
이때 event.code
프로퍼티가 가지는 키의 코드값은 다음의 형태로 구분할 수 있다.
Key<문자>
ex) KeyZ
, KeyA
Digit<숫자>
ex) Digit0
, Digit1
Enter
, Backspace
, Tab
물론 대소문자 구분이 없는 특수한 키의 경우에는 event.key
와 event.code
프로퍼티의 값이 동일한 경우도 있다. 그렇지만 event.code
는 특수키의 경우에도 조금 더 세부적인 부분까지 구분한다.
Key | event.key | event.code |
---|---|---|
F1 | F1 | F1 |
Backspace | Backspace | Backspace |
Shift | Shift | ShiftRight 또는 ShiftLeft |
event.key
프로퍼티는 단순히 어떤 키가 눌렸는지에 대한 정보를 가지고 있다고 볼 수 있다. 따라서 Shift
키의 경우에는 해당 키가 왼쪽 시프트인지, 오른쪽 시프트인지는 구분하지 않는다. 반면 event.code
는 키의 코드값을 가지기 때문에 동일한 특수키에 대해서는 조금 더 세부적인 정보를 함께 출력함을 볼 수 있다.
그렇다면 어떠한 경우에 event.key
를 사용할 지 event.code
를 사용할 지 결정할 수 있을까? 단축키 중에 Ctrl + z
를 사용한다고 생각해보자. 대부분의 텍스트 에디터에서 해당 단축키는 이전으로 되돌아가는 작업을 수행한다. 우리는 해당 이벤트를 keydown
핸들러를 통해 잡아낸다고 가정하자. 그렇다면 event.key
와 event.code
중에 어떠한 프로퍼티를 사용하는 것이 더 좋을까?
물론 두 가지 프로퍼티 모두 원하는 동작을 수행하는 것은 문제없다. 그러나 event.key
의 경우에는 지금 누른 키 자체를 가지고 있기 때문에, 대소문자 처리와 같은 부가적인 작업이 필요하다. 그러나 event.code
의 경우엔 항상 동일한 키 코드값을 가지기 때문에 보다 편하게 해당 작업을 처리할 수 있다.
document.addEventListener('keydown', function(event) {
if (event.code === 'KeyZ' && (event.ctrlKey || event.metaKey)) {
alert('Undo!');
}
});
그러나 다음의 경우에는 event.code
가 문제가 될 수 있다. 키보드가 취하고 있는 언어의 형태와 배열에 의해 각각 다른 값을 가질 수 있다. 이러한 언어 체계는 나라마다 운영체제에 의해 다르게 구현될 수 있는데 대표적인 예로 미국의 자판과 독일의 자판을 들 수 있다.
나라마다 이처럼 키보드 레이아웃이 다를 수 있는데 이와 같이 서로 상이한 레이아웃에 의해서 예측하지 못한 동작이 발생할 수 있다. 이러한 경우는 사실 흔치 않은 경우이고 그나마 해당 사례의 대부분은 KeyA
, KeyZ
, KeyQ
등에서 많이 발발한다. 그럼에도 조금 더 신뢰도 높은 처리를 위해서는 event.key
가 조금 더 좋은 방법이 될 수 있다. 두 프로퍼티의 쓰임을 대체로 정리하자면 다음과 같다.
event.key
: 레이아웃에 의존적인 키를 다루고자 하는 경우event.code
: 언어별 체계가 다르더라도 hotkey
와 같이 단축키 등을 다루고자 하는 경우키는 눌렀다 떼었다를 반복할 수도 있지만, 하나의 키가 계속 눌려진 상태를 유지할 수 있다. 이 경우를 자동 반복(auto-repeat
)이라는 상태로 구분하는데, 이는 keydown
이 계속해서 반복 호출되는 상태를 말한다. 최종적으로는 keyup
이벤트가 최소 한 번 발생할 것이다. 따라서 keydown
과 keyup
이벤트의 상관관계는 항상 1:1
이 아닌 n:1
이 될 수도 있다.
이러한 상태를 체크할 수 있는 프로퍼티도 제공되는데 만약 auto-repeat
의 상태인 경우엔 event.repeat
프로퍼티가 true
값을 가진다.
키보드의 몇몇 특수키는 브라우저에서 다양한 기본 동작을 가진다. 예를 들면 다음과 같은 동작들이 있다.
Delete
: 문자를 앞에서 뒤 방향으로 하나씩 제거PageDown
: 페이지를 아래로 스크롤링Ctrl + S
: 브라우저에서는 현재 페이지를 저장하는 창을 출력...
이러한 기본 동작은 앞서 보았던 바와 같이 keydown
이벤트에서 false
를 리턴함으로써 대부분 방지가 가능하다. 물론 이러한 방식으로도 취소할 수 없는 기본 동작도 있다. 예를 들어 Alt + F4
는 현재 브라우저 창을 닫는 단축키인데 자바스크립트 상으로는 해당 동작 자체를 방지할 수 있는 방법은 없다.
운영체제 자체에 정의된 특수한 단축키에 정의된 기본 동작 외에는 동작을 방지하기 위해 키 입력을 불가능하게 만들어주면 된다. 다음과 같은 <input>
요소에서는 휴대폰 번호를 입력받게 하는데, 숫자와 +
, ()
, -
문자를 제외한 나머지 값들은 입력받지 않도록 하고 있다.
<script>
function checkPhoneKey(key){
return (key >= '0' && key <= '9') || key == '+' || key == '(' || key == ')' || key == '-';
}
</script>
<input onkeydown="return checkPhoneKey(event.key)" placeholder="휴대폰 번호를 입력하세요" type="tel">
그런데 위와 같이 작성하게 되면 Backspace
, 화살표 이동키
, ctrl + V
와 같은 특수키 역시 동작을 막게 된다. 단적으로 숫자를 잘못 기입한 경우엔 이를 제대로 지울 수가 없다. 때문에 보다 엄격한 필터링이 필요한데, 이를 적용하면 다음과 같다.
function checkPhoneKey(key) {
return (key >= '0' && key <= '9') || key == '+' || key == '(' || key == ')' || key == '-' ||
key == 'ArrowLeft' || key == 'ArrowRight' || key == 'Delete' || key == 'Backspace';
}
이처럼 수정한다면 의도한대로 동작하겠지만 일일이 허용해야할 키를 기입하는 것은 매우 번거로운 작업이다. 또한 마우스 클릭 등을 통한 복사/붙여넣기는 여전히 가능하기도 하다. 즉 이처럼 필터링을 구현하는 것은 모든 요소를 다 고려해주어야 하기 때문에 만들기가 매우 까다롭다.
과거에 키보드 입력 관련으로 사용하던 이벤트는 keypress
였다. 해당 이벤트는 keyCode
, charCode
, which
등의 프로퍼티를 가지고있고 이를 통해 위와 같은 일련의 작업을 수행할 수 있다.
이는 아직 브라우저의 하위 호환성을 위해 제거되지 않고 남아있지만 가급적 위에서 언급한 모던 이벤트인 keydown/up
이벤트와 그에 관련된 프로퍼티를 사용하는 것을 추천한다.
노트북의 키보드 등에서 찾아볼 수 있는 펑션키(
Fn
)는 보통 키보드 이벤트에서 감지할 수 없는 경우도 있다.
scroll
이벤트는 페이지나 요소에서 발생하는 스크롤에 반응한다. 스크롤 이벤트를 통해 다음과 같은 작업을 처리할 수 있다.
특히 두 번째 기능의 경우 Infinite Scroll
이라는 용어로 많이 접할 수 있으며, 모던 웹 페이지에서 가히 필수적으로 구현되는 요소 중에 하나이다. 서버로부터 모든 데이터를 한 번에 가져오는 것은 심각한 리소스 낭비이기 때문의 사용자의 스크롤 위치로부터 가져올 데이터를 판단하고 조금씩 가져오면 해당 리소스를 상당 부분 아낄 수 있기 때문이다.
스크롤 이벤트는 앞서 살펴본 이벤트에서 event.preventDefault()
를 통해 막았던 것처럼 방지할 수가 없다. 왜냐하면 스크롤 이벤트는 브라우저 상에서 최적화 성능을 위해 따로 이벤트 핸들러에 감지되기 전에 미리 동작을 수행하고, 그 뒤에 핸들러가 이를 잡아내는 순서로 진행되기 때문이다.
그렇지만 pageDown
이나 pageUp
등과 같이 키보드 입력으로 발생하는 스크롤 이벤트는 event.preventDefault()
를 사용해서 막을 수 있다.
보통 스크롤 이벤트를 막기 위해서는 자바스크립트로 접근하기 보다는 CSS에서 overflow
속성을 통해 아예 스크롤을 없애는 방향을 진행하는 편이 많다.