[TypeScript] 포인터 대통합(with. PointerEvent)

고라니드로고라니드로
2 min read

PointerEvent는 포인터 유형(마우스, 터치 등)을 동일하게 처리하기 위한 이벤트입니다. 이를 활용하면 MouseEventTouchEvent를 함께 사용해야 하는 문제를 더 쉽게 해결할 수 있습니다. 근본적으로 MouseEvent를 상속하기 때문에 이와 유사하게 사용할 수 있습니다.

// MouseEvent
element.addEventListener("mouseup", e => console.log(e.clientX, e.clientY));

// PointerEvent
element.addEventListener("pointerup", e => console.log(e.clientX, e.clientY));

포인터 이벤트의 유형에 대한 자세한 내용은 MDN 문서를 통해 확인할 수 있습니다. 본 포스트는 기존 방법의 문제점과 PointerEvent 사용 시 염두에 두어야 할 점 등에 초점을 맞춥니다.

MouseEventTouchEvent의 문제점

기존에는 MouseEventTouchEvent를 결합하여 이를 처리할 수 있었습니다. 둘은 매우 다른 형태를 띠고 있어 구현 복잡성이 증가합니다. 물론 이는 사소한 문제로 여겨질 수 있으며, 진짜 문제는 따로 있습니다.

터치스크린에서는 TouchEventMouseEvent가 모두 발생합니다. 중복 핸들링을 피하기 위해서는 이 중 하나를 차단해야 합니다. 하지만 기기가 여러 종류의 포인터를 취급할 수 있기 때문에 사전에 차단하는 것은 적절치 않습니다.

TouchEvent에서 preventDefault를 호출하면 MouseEvent의 호출을 차단할 수 있기 때문에 일반적으로 이 방법이 제시됩니다. 실제 MDN 문서에서도 언급하고 있습니다. 하지만 TouchEvent는 항상 취소할 수 있는 것이 아닙니다. 취소할 수 없는 경우, MouseEvent의 호출을 막을 수 없습니다. 당장 문제없는 것처럼 보일 수 있지만 이는 견고하지 않습니다.

PointerEvent 사용 시 숙지할 점

PointerEvent는 본디 모든 종류의 포인터를 수용하도록 설계되었습니다. 따라서 위와 같은 문제는 발생하지 않습니다. 하지만 몇 가지 숙지하면 좋은 것들이 있습니다.

  1. 버튼의 종류를 구분해야 할 수 있습니다. button 속성을 사용하여 이를 구분할 수 있습니다.

  2. 모든 이벤트가 항상 정상 완료되는 것은 아닙니다. 이벤트가 도중에 취소되어 pointerup에 도달하지 못할 수 있습니다. 이 때에는 pointercancel을 통해 이를 처리해야 합니다.

  3. 터치에 대해서는 pointermove가 브라우저 기본 동작에 의해 취소됩니다. 이를 방지하기 위해서는 touchstart에서 preventDefault를 호출하거나, CSS에서 touch-actionnone으로 설정하는 등의 방법으로 기본 동작을 차단해야 합니다.

  4. 브라우저 기본 드래그 앤 드롭 동작에 의해서 취소될 수 있습니다. 이를 방지하기 위해서는 pointerdown 또는 dragstart에서 preventDefault를 호출하여 기본 동작을 차단해야 합니다.

  5. 터치에 대해서는 pointerdown에서 암시적 포인터 캡처가 이루어집니다. 포인터 캡처요소 밖의 포인터도 추적하는 것을 말합니다. 요소 밖에서도 pointermove를 감지할 수 있는 장점이 있지만 pointerleave를 감지하지 못하는 단점도 함께 존재합니다. 포인터 캡처는 한 요소에 대해 전역적이기 때문에 다른 핸들러에 의해 설정되거나 취소될 수 있습니다. 따라서 한쪽을 가정하는 것은 바람직하지 않을 수 있습니다.

위 사항만 숙지한다면 보다 안전하게 PointerEvent를 활용할 수 있습니다.

읽어주셔서 감사합니다!

묻고 답하기

개인적인 판단에 의해 적절하다고 여겨지는 경우, 모두가 볼 수 있도록 이곳에 문답이 추가됩니다. 그렇지 않더라도 질문에 대한 답변은 별도로 이루어집니다.

0
Subscribe to my newsletter

Read articles from 고라니드로 directly inside your inbox. Subscribe to the newsletter, and don't miss out.

Written by

고라니드로
고라니드로