나아갈 방향을 가리키기

Sérgio Gomes

이전에는 웹에서 사물을 가리키는 것이 간단했습니다. 이전에 사용하던 마우스를 움직였습니다. 때로는 버튼을 눌렀죠. 그게 전부였습니다. 일반적이지 않은 모든 것은 마우스가 하나로 에뮬레이트되었고, 개발자들은 무엇을 의존해야 하는지 정확히 알고 있었습니다.

그렇다고 단순함이 반드시 좋은 것은 아닙니다. 시간이 지나면서 모든 것이 쥐가 아니었다는 것 (또는 쥐인 것처럼 가장)이 아니었다는 점이 중요합니다. 놀라운 창작의 자유를 선사하는 압력 감지 및 기울기 인식 펜 할 수 있습니다 기기와 손만 있으면 됩니다. 이봐, 왜 손가락 두 개 이상을 사용하지 않는다면 어떻게 해야 할까요?

터치 이벤트가 있었음 당분간은 이 작업에 도움이 되지만, 두 API는 완전히 별개의 API입니다. 특히 터치의 경우 두 개의 개별 이벤트 모델을 코딩해야 하므로 마우스와 터치를 모두 지원해야 합니다. Chrome 55에 새로운 표준이 탑재됨 두 모델을 통합하는 포인터 이벤트입니다.

단일 이벤트 모델

포인터 이벤트는 터치, 펜, 마우스를 함께 제공하는 브라우저용 포인터 입력 모델 전달할 수 있습니다 예를 들면 다음과 같습니다.

document.addEventListener('pointermove',
    ev => console.log('The pointer moved.'));
foo.addEventListener('pointerover',
    ev => console.log('The pointer is now over foo.'));

사용 가능한 모든 이벤트 목록은 다음과 같습니다. 마우스 이벤트에 익숙해야 합니다.

pointerover 포인터가 요소의 경계 상자에 들어갔습니다. 이는 마우스 오버를 지원하는 기기에서 즉시 발생하거나 pointerdown 이벤트를 사용합니다.
pointerenter pointerover와 유사하지만 대화창 및 핸들로 표시되지 않음 다르게 나타납니다. 사양 세부정보
pointerdown 포인터가 활성 버튼 상태로 전환되었습니다. 프레미스의 의미에 따라 눌러야 하는 입력 장치입니다.
pointermove 포인터 위치가 변경되었습니다.
pointerup 포인터가 활성 버튼 상태에서 벗어났습니다.
pointercancel 문제가 발생했습니다. 즉, 포인터가 아무 것도 내보낼 가능성이 낮습니다. 더 많은 이벤트를 볼 수 있습니다. 즉, 진행 중인 작업을 취소하고 중립 입력 상태로 돌아갑니다
pointerout 포인터가 요소 또는 화면의 경계 상자를 떠났습니다. 또한 pointerup: 기기에서 마우스 오버를 지원하지 않는 경우
pointerleave pointerout와 유사하지만 대화창 및 핸들로 표시되지 않음 다르게 나타납니다. 사양 세부정보
gotpointercapture 요소가 포인터 캡처를 수신했습니다.
lostpointercapture 캡처 중이었던 포인터가 출시되었습니다.

다양한 입력 유형

일반적으로 포인터 이벤트를 사용하면 입력에 구애받지 않는 방식으로 코드를 작성할 수 있습니다. 여러 입력 장치에 대해 별도의 이벤트 핸들러를 등록할 필요가 없습니다. 물론 여전히 입력 유형 간의 차이점(예: 마우스 오버의 개념이 적용됩니다. 다양한 입력 장치 유형을 구분하려는 경우(예: 다양한 입력에 대해 별도의 코드/기능을 구현할 수 있습니다. 하지만 pointerType 속성을 사용하여 이벤트 핸들러 내에 PointerEvent 인터페이스에 추가되었습니다. 예를 들어 측면 탐색 창을 코딩하는 경우 pointermove 이벤트에 다음과 같은 로직이 있어야 합니다.

switch(ev.pointerType) {
    case 'mouse':
    // Do nothing.
    break;
    case 'touch':
    // Allow drag gesture.
    break;
    case 'pen':
    // Also allow drag gesture.
    break;
    default:
    // Getting an empty string means the browser doesn't know
    // what device type it is. Let's assume mouse and do nothing.
    break;
}

기본 작업

터치를 사용할 수 있는 브라우저에서는 특정 동작이 페이지를 스크롤, 확대/축소 또는 새로고침하는 데 사용됩니다. 터치 이벤트의 경우 이러한 기본 컨트롤이 있는 동안에도 이벤트를 계속 수신합니다. 발생합니다. 예를 들어 사용자가 스크롤하는 동안 touchmove가 계속 실행됩니다.

포인터 이벤트를 사용하면 스크롤 또는 확대/축소와 같은 기본 작업이 트리거될 때마다 pointercancel 이벤트가 수신되어 브라우저가 제어할 수 있습니다. 예를 들면 다음과 같습니다.

document.addEventListener('pointercancel',
    ev => console.log('Go home, the browser is in charge now.'));

기본 제공 속도: 이 모델은 기본적으로 더 나은 성능을 허용합니다. 인코더에 전달합니다. 패시브 이벤트 리스너 동일한 수준의 응답성을 달성할 수 있습니다

원하는 경우 브라우저에서 touch-action 드림 CSS 속성 요소에서 none로 설정하면 모두 사용 중지됩니다. 브라우저에서 정의된 작업이 해당 요소에서 시작된 것입니다. 하지만 데이터 애널리스트가 사용할 수 있는 더 세밀하게 제어할 수 있는 다른 값(예: pan-x)이 브라우저가 x축의 움직임에 반응하지만 y축에서는 반응하지 않습니다. Chrome 55 는 다음 값을 지원합니다.

auto 기본값; 브라우저가 모든 기본 작업을 수행할 수 있습니다.
none 브라우저에서 기본 작업을 수행할 수 없습니다.
pan-x 브라우저에서는 가로 스크롤 기본 작업만 실행할 수 있습니다.
pan-y 브라우저에서는 세로 스크롤 기본 작업만 실행할 수 있습니다.
pan-left 브라우저는 가로 스크롤 기본 작업만 수행할 수 있습니다. 페이지를 왼쪽으로만 이동합니다.
pan-right 브라우저는 가로 스크롤 기본 작업만 수행할 수 있습니다. 페이지를 오른쪽으로 이동하기만 하면 됩니다.
pan-up 브라우저는 세로 스크롤 기본 작업만 수행할 수 있습니다. 페이지 위로 이동만 할 수 있습니다.
pan-down 브라우저는 세로 스크롤 기본 작업만 수행할 수 있습니다. 페이지 아래로 이동만 할 수 있습니다.
manipulation 브라우저에서는 스크롤 및 확대/축소 작업만 실행할 수 있습니다.

포인터 캡처

손상된 mouseup를 디버깅하는 데 불편한 시간을 겪은 적이 있음 사용자가 버튼에서 손을 떼는 것이 원인이라는 것을 알아차릴 때까지 어떻게 해야 할까요? 없으시다면 그럼, 나만 그런 걸지도 몰라.

하지만 지금까지는 이 문제를 해결할 수 있는 좋은 방법이 없었습니다. 물론입니다. 문서에 mouseup 핸들러를 설정하고 일부 상태를 해야 할 일들을 추적할 수 있습니다. 그것이 가장 깔끔한 해결책은 아니고 특히 웹 구성요소를 빌드하고 모든 것을 멋지고 있습니다.

포인터 이벤트를 사용하면 훨씬 더 나은 솔루션이 제공됩니다. 포인터를 캡처할 수 있고, 그러면 해당 pointerup 이벤트 (또는 기타 어려운 이벤트)를 가져올 수 있습니다. 합니다.

const foo = document.querySelector('#foo');
foo.addEventListener('pointerdown', ev => {
    console.log('Button down, capturing!');
    // Every pointer has an ID, which you can read from the event.
    foo.setPointerCapture(ev.pointerId);
});

foo.addEventListener('pointerup', 
    ev => console.log('Button up. Every time!'));

브라우저 지원

이 문서 작성 시점을 기준으로 포인터 이벤트는 Internet Explorer 11에서 지원되므로 Microsoft Edge, Chrome, Opera를 지원하며 Firefox에서 부분적으로 지원됩니다. 다음과 같은 작업을 할 수 있습니다. caniuse.com에서 최신 목록을 확인하세요.

포인터 이벤트 폴리필을 사용하여 격차를 메워줍니다 또는 런타임에 브라우저 지원을 확인하는 것은 명확성:

if (window.PointerEvent) {
    // Yay, we can use pointer events!
} else {
    // Back to mouse and touch events, I guess.
}

포인터 이벤트는 점진적 개선에 바람직한 후보입니다. 초기화 메서드를 수정하여 위에서 확인하고 포인터 이벤트를 추가합니다. if 블록의 핸들러에 배치하고 마우스/터치 이벤트 핸들러를 else 블록.

한번 사용해 보시고 여러분의 의견을 알려주세요.