Copyright © 2026 World Wide Web Consortium. W3C® liability, trademark and permissive document license rules apply.
Pointer Events 명세는 마우스, 터치스크린, 펜/스타일러스 등 다양한 장치의 입력을 처리하기 위한 통합된 하드웨어 독립적 프레임워크를 정의한다. 단일 이벤트 집합(예: pointerdown, pointermove, pointerup)을 제공함으로써 개발자가 각 장치별 논리를 작성하지 않고도 다양한 입력 방식을 지원할 수 있도록 한다.
이 명세는 Mouse 및 Wheel 이벤트와 다른 포인터 장치 유형에 대해 Mouse 이벤트를 발생시키기 위한 매핑도 정의한다.
이 절에서는 이 문서가 공개된 시점의 상태를 설명한다. 현재 W3C 출판물 목록과 이 기술 보고서의 최신 개정판은 W3C 표준 및 초안 색인에서 확인할 수 있다.
이 명세는 [PointerEvents3] 명세의 업데이트이다. 또한 이전에 [UIEVENTS] 명세에 있던 Mouse 및 Wheel 이벤트를 포함한다.
이번 개정판에는 다음과 같은 새로운 기능이 포함된다:
persistentDeviceId.touch-action 값: pan-left,
pan-right, pan-up, pan-down
이 문서는 Pointer Events 작업 그룹이 권고안 트랙을 사용하여 작업 초안으로 공개했다.
작업 초안으로 공개되었다고 해서 W3C 및 그 회원들이 이를 승인한다는 의미는 아니다.
이 문서는 초안이며 언제든지 다른 문서에 의해 업데이트, 대체 또는 폐기될 수 있다. 이 문서를 진행 중인 작업 이외의 것으로 인용하는 것은 적절하지 않다.
이 문서는 W3C 특허 정책에 따라 운영되는 그룹에서 작성했다. W3C는 해당 그룹의 결과물과 관련하여 이루어진 모든 특허 공개의 공개 목록을 유지한다. 해당 페이지에는 특허를 공개하기 위한 지침도 포함되어 있다. 자신이 필수 청구항을 포함한다고 판단하는 특허를 실제로 알고 있는 개인은 W3C 특허 정책 제6절에 따라 해당 정보를 공개해야 한다.
이 문서는 2025년 8월 18일 W3C 프로세스 문서의 적용을 받는다.
이 섹션은 비규범적이다.
오늘날 대부분의 [HTML] 콘텐츠는 마우스 입력과 함께 사용되거나 마우스 입력을 위해 설계된다. 입력을 사용자 정의 방식으로 처리하는 콘텐츠는 일반적으로 Mouse 이벤트에 맞춰 코드를 작성한다. 그러나 오늘날의 최신 컴퓨팅 장치는 터치스크린과 펜 입력을 비롯한 다른 형태의 입력도 포함한다. 이러한 각 입력 형태를 개별적으로 처리하기 위한 이벤트 유형이 제안되어 왔다. 그러나 이러한 접근 방식은 새로운 입력 유형에 대한 지원을 추가할 때 불필요한 논리 중복과 이벤트 처리 오버헤드를 발생시키는 경우가 많다. 또한 콘텐츠가 하나의 장치 유형만을 염두에 두고 작성되면 호환성 문제가 발생하는 경우가 많다. 또한 기존의 마우스 기반 콘텐츠와의 호환성을 위해 대부분의 사용자 에이전트는 모든 입력 유형에 대해 Mouse 이벤트를 발생시킨다. 이로 인해 Mouse 이벤트가 실제 마우스 장치를 나타내는 것인지, 아니면 호환성을 위해 다른 입력 유형에서 생성된 것인지가 모호해져 두 장치 유형을 동시에 처리하는 코드를 작성하기 어려워진다.
여러 입력 유형을 처리하기 위한 코딩 비용을 줄이고 위에서 설명한 Mouse 이벤트의 모호성을 해결하기 위해 이 명세에서는 포인터라고 하는 보다 추상적인 형태의 입력을 정의한다. 포인터는 마우스 커서, 펜, 터치(멀티터치 포함) 또는 기타 포인팅 입력 장치가 화면에 만드는 모든 접촉점일 수 있다. 이 모델을 사용하면 사용자가 어떤 하드웨어를 가지고 있든 잘 작동하는 사이트와 애플리케이션을 더 쉽게 작성할 수 있다. 장치별 처리가 필요한 경우를 위해 이 명세에서는 이벤트를 생성한 장치 유형을 검사하기 위한 속성도 정의한다. 주요 목표는 장치 간 포인터 입력을 더 쉽게 작성할 수 있게 하는 단일 이벤트 및 인터페이스 집합을 제공하는 동시에, 향상된 경험을 위해 필요한 경우에만 장치별 처리를 허용하는 것이다.
또 다른 주요 목표는 멀티스레드 사용자 에이전트가 직접 조작 방식의 패닝 및 확대/축소 동작(예: 터치스크린에서 손가락이나 스타일러스를 사용하는 경우)을 스크립트 실행을 차단하지 않고 처리할 수 있도록 하는 것이다.
이 명세에서는 다양한 포인터 입력을 위한 통합 이벤트 모델을 정의하지만, 이 모델은 키보드 또는 키보드와 유사한 인터페이스와 같은 다른 형태의 입력은 다루지 않는다(예를 들어, 터치스크린 전용 장치에서 실행되며 사용자가 포커스 가능한 컨트롤과 요소를 순차적으로 탐색할 수 있게 하는 스크린 리더 또는 이와 유사한 보조 기술). 사용자 에이전트가 이러한 인터페이스에 대한 응답으로 포인터 이벤트도 생성하도록 선택할 수 있지만, 이러한 시나리오는 이 명세에서 다루지 않는다.
우선 저자는 focus, blur 및
click과 같은 상위 수준 이벤트에 응답하여 모든 형태의
입력에 대해 동등한 기능을 제공하도록 권장된다. 그러나 저수준 이벤트(예: Pointer 이벤트)를 사용할 때 저자는
모든 유형의 입력이 지원되도록 하는 것이 권장된다. 키보드 및
키보드와 유사한 인터페이스의 경우 명시적인 키보드 이벤트 처리를 추가해야 할 수도 있다. 자세한
내용은 키보드 접근성 [WCAG22]을 참조한다.
일반적인 포인터 입력을 처리하기 위한 이벤트는 마우스용 이벤트와 매우 유사하다: pointerdown,
pointermove, pointerup, pointerover, pointerout 등이 있다. 이를 통해 콘텐츠를
Mouse 이벤트에서 Pointer 이벤트로 쉽게 마이그레이션할 수 있다.
Pointer 이벤트는 Mouse 이벤트에 존재하는 일반적인 모든 속성(클라이언트 좌표,
대상 요소, 버튼 상태 포함)뿐만 아니라 압력,
접촉 형상, 기울기와 같은 다른 형태의 입력을 위한 새로운 속성도 제공한다. 저자는 적절한 경우 서로 다른 입력
유형 간에 논리를 공유하도록 Pointer 이벤트에 맞춰 코드를 쉽게 작성할 수 있으며, 최상의 경험을 얻기 위해 필요한
경우에만 특정 입력 유형에 맞게 사용자 정의할 수 있다.
Pointer 이벤트는 다양한 입력 장치에서 발생하지만, 다른 장치별 이벤트 집합으로부터 생성되는 것으로 정의되지 않는다. 호환성을 위해 그렇게 하는 것이 가능하며 권장되지만, 이 명세는 다른 장치별 이벤트(예: 마우스 이벤트 또는 터치 이벤트)의 지원을 요구하지 않는다. 사용자 에이전트는 다른 어떤 장치 이벤트도 지원하지 않고 포인터 이벤트만 지원할 수 있다. 마우스별 이벤트를 대상으로 작성된 콘텐츠와의 호환성을 위해 이 명세에서는 마우스 이외의 장치에서 발생하는 포인터 입력을 기반으로 호환성 마우스 이벤트를 생성하는 방법을 설명하는 선택적 섹션을 제공한다.
이 명세는 Touch 이벤트([TOUCH-EVENTS]에서 정의됨)와 Pointer 이벤트를 모두 지원하는 사용자 에이전트의 예상 동작에 대한 어떠한 조언도 제공하지 않는다. 이 두 명세 간의 관계에 대한 자세한 내용은 Touch Events 커뮤니티 그룹을 참조한다.
비규범적으로 표시된 섹션뿐만 아니라 이 명세의 모든 작성 지침, 다이어그램, 예제 및 참고 사항은 비규범적이다. 이 명세의 그 밖의 모든 내용은 규범적이다.
이 문서에서 핵심어 MAY, MUST, MUST NOT, OPTIONAL 및 SHOULD는 여기에서와 같이 모두 대문자로 표시되는 경우에만 BCP 14 [RFC2119] [RFC8174]에 설명된 대로 해석해야 한다.
WebIDLdictionary PointerEventInit : MouseEventInit {
long pointerId = 0;
double width = 1;
double height = 1;
float pressure = 0;
float tangentialPressure = 0;
long tiltX;
long tiltY;
long twist = 0;
double altitudeAngle;
double azimuthAngle;
DOMString pointerType = "";
boolean isPrimary = false;
long persistentDeviceId = 0;
sequence<PointerEvent> coalescedEvents = [];
sequence<PointerEvent> predictedEvents = [];
};
[Exposed=Window]
interface PointerEvent : MouseEvent {
constructor(DOMString type, optional PointerEventInit eventInitDict = {});
readonly attribute long pointerId;
readonly attribute double width;
readonly attribute double height;
readonly attribute float pressure;
readonly attribute float tangentialPressure;
readonly attribute long tiltX;
readonly attribute long tiltY;
readonly attribute long twist;
readonly attribute double altitudeAngle;
readonly attribute double azimuthAngle;
readonly attribute DOMString pointerType;
readonly attribute boolean isPrimary;
readonly attribute long persistentDeviceId;
[SecureContext] sequence<PointerEvent> getCoalescedEvents();
sequence<PointerEvent> getPredictedEvents();
};
pointerId이벤트를 발생시키는 포인터의 고유 식별자. 사용자 에이전트는 주 마우스 포인터에 대해
일반적인 pointerId
값으로
0 또는 1을 예약할 수 있다. pointerId 값
-1은 포인팅 장치가 아닌 다른 것에 의해 생성된 이벤트를 나타내기 위해
예약하고 사용해야 한다. 그 밖의 모든 포인터에 대해 사용자
에이전트는 pointerId
값을 할당하는 방식에 서로 다른 전략과 접근 방식을 자유롭게 구현할 수 있다.
그러나 최상위
브라우징 컨텍스트([HTML]에서 정의됨)의 모든
활성 포인터는 고유해야 하며,
식별자는 다른 어떤 최상위 브라우징 컨텍스트의 영향도 받아서는 안 된다(즉, 하나의 최상위 브라우징 컨텍스트는
포인터가 해당 브라우징 컨텍스트 밖으로 이동하여 다른 최상위 브라우징 컨텍스트로
들어갈 때 포인터의 pointerId가 동일할 것이라고
가정할 수 없다).
사용자 에이전트는
이전 활성 포인터에서 더 이상 사용되지 않는 pointerId 값을 재사용할
수 있으며, 특정 포인팅 장치에 대해 항상 동일한 pointerId를
재사용할 수도 있다(예를 들어 다중 사용자 협업 애플리케이션에서
특정 사용자의 특정 펜/스타일러스 입력을 고유하게 식별하기 위해). 그러나 후자의
경우 서로 다른 페이지나 도메인에 걸친 핑거프린팅 및 추적 가능성을 최소화하기 위해
pointerId는
페이지/세션의 수명 동안에만 해당 특정 포인팅 장치와 명시적으로 연결해야 하며, 해당 특정 포인팅 장치를 새 세션에서
다시 사용할 때는
새로 무작위화된 pointerId를 선택해야 한다.
pointerId 선택
알고리즘은 구현별로 다르다. 저자는 값이 다른 모든 활성 포인터와 구별되는
포인터의 식별자라는 것 이외에 특정 의미를 전달한다고 가정할 수 없다.
예를 들어 사용자 에이전트는 활성화되는 순서대로 모든 활성 포인터에
0부터 시작하는 숫자를 단순히 할당할 수 있지만, 이러한 값이
단조 증가한다고 보장되지는 않는다. 특정 포인팅 장치에 동일한 pointerId를
재사용할지 여부는 각 구현에 맡겨져 있으므로, 저자는 이에 의존하지 않는 것이
강력히 권장되며 대신 persistentDeviceId를
참조하는 것이 좋다.
width포인터의 접촉 형상의 너비(X축 방향 크기)를
CSS 픽셀 단위로 나타낸 값([CSS21] 참조).
이 값은 주어진 포인터의 각 이벤트에서 갱신될 수 있다. 일반적으로 접촉 형상이 없는 입력
(예: 전통적인 마우스)과 입력의 실제 형상이 하드웨어에서 감지되지 않는 경우
사용자 에이전트는 기본값
1을 반환해야 한다.
height포인터의 접촉 형상의 높이(Y축 방향 크기)를
CSS 픽셀 단위로 나타낸 값([CSS21] 참조).
이 값은 주어진 포인터의 각 이벤트에서 갱신될 수 있다. 일반적으로 접촉 형상이 없는 입력
(예: 전통적인 마우스)과 입력의 실제 형상이 하드웨어에서 감지되지 않는 경우
사용자 에이전트는 기본값
1을 반환해야 한다.
pressure[0,1] 범위로 정규화된 포인터 입력의 압력으로,
0과 1은 각각 하드웨어가 감지할 수 있는 최소 및 최대 압력을
나타낸다. 압력을 지원하지 않는 하드웨어 및 플랫폼에서는 활성 버튼 상태일 때 값이
0.5이어야 하며, 그렇지 않을 때는
0이어야 한다.
tangentialPressure일반적으로 추가 컨트롤(예: 에어브러시 스타일러스의 핑거 휠)에 의해 설정되는
포인터 입력의 정규화된 접선 압력(배럴 압력이라고도 함)으로,
[-1,1] 범위이며 0은 컨트롤의 중립 위치이다.
일부 하드웨어는 [0,1] 범위의 양수 값만 지원할 수 있음에 유의한다.
접선 압력을 지원하지 않는 하드웨어 및 플랫폼의 경우 값은 반드시 0이어야 한다.
tiltXY-Z 평면과 트랜스듀서(예: 펜/스타일러스) 축 및 Y축을 모두 포함하는 평면 사이의
평면각(도 단위, [-90,90] 범위)이다. 양의
tiltX는 X 값이 증가하는 방향인 오른쪽이다.
tiltX는 tiltY와 함께 사용하여 디지타이저에 대한
트랜스듀서의 법선에서 벗어난 기울기를 나타낼 수 있다. 기울기나 각도를 보고하지 않는
하드웨어 및 플랫폼의 경우 값은 반드시 0이어야 한다.
tiltX.
tiltYX-Z 평면과 트랜스듀서(예: 펜/스타일러스) 축 및 X축을 모두 포함하는 평면 사이의
평면각(도 단위, [-90,90] 범위)이다. 양의
tiltY는 Y 값이 증가하는 방향인 사용자 쪽이다.
tiltY는 tiltX와 함께 사용하여 디지타이저에 대한
트랜스듀서의 법선에서 벗어난 기울기를 나타낼 수 있다. 기울기나 각도를 보고하지 않는
하드웨어 및 플랫폼의 경우 값은 반드시 0이어야 한다.
tiltY.
twist트랜스듀서(예: 펜/스타일러스)가 자체 주축을 중심으로 시계 방향으로 회전한 정도
(도 단위, [0,359] 범위)이다. twist를 보고하지 않는 하드웨어 및 플랫폼의 경우
값은 반드시 0이어야 한다.
altitudeAngle트랜스듀서(예: 펜/스타일러스)의 고도각(라디안 단위)으로,
[0,π/2] 범위이다. 여기서 0은 표면(X-Y 평면)과 평행하고,
π/2는 표면에 수직이다. 기울기나 각도를 보고하지 않는 하드웨어 및 플랫폼의 경우
값은 반드시 π/2이어야 한다.
altitudeAngle에 대해 정의된 기본값은 π/2이며,
이는 트랜스듀서가 표면에 수직으로 위치함을 나타낸다.
이는 기본값이
0인 Touch Events - Level
2 명세의
altitudeAngle 속성 정의와 다르다.
π/4인
altitudeAngle의 예(X-Y
평면으로부터 45도).azimuthAngle트랜스듀서(예: 펜/스타일러스)의 방위각(라디안 단위)으로,
[0, 2π] 범위이다. 여기서 0은 X-Y 평면에서 트랜스듀서의 캡이
X 값이 증가하는 방향을 가리키는 상태(수직으로 내려다보았을 때 "3시" 방향)를 나타내며,
시계 방향으로 갈수록 값이 점진적으로 증가한다(π/2는
"6시", π는 "9시", 3π/2는 "12시"). 트랜스듀서가
표면에 완전히 수직일 때(altitudeAngle이
π/2) 값은 반드시 0이어야 한다.
기울기나 각도를 보고하지 않는 하드웨어 및 플랫폼의 경우 값은 반드시 0이어야 한다.
π/6인
azimuthAngle의 예("4시").pointerType이벤트를 발생시킨 장치 유형(예: 마우스, 펜, 터치)을 나타낸다. 사용자
에이전트가 마우스, 펜/스타일러스 또는 터치 입력 장치에 대해 포인터 이벤트를 발생시키는 경우
pointerType 값은 반드시 다음 표를 따라야 한다:
| 포인터 장치 유형 | pointerType 값 |
|---|---|
| 마우스 | mouse |
| 펜 / 스타일러스 | pen |
| 터치 접촉 | touch |
사용자 에이전트가 장치 유형을 감지할 수 없는 경우 값은 반드시 빈 문자열이어야 한다. 사용자 에이전트가 위에 나열된 것
이외의 포인터 장치 유형을 지원하는 경우 서로 다른 장치 유형의 이름 충돌을 방지하기 위해
pointerType 값에 공급업체 접두사를 붙이는 것이 좋다. 향후 명세에서 다른 장치 유형에
대해 추가적인
규범적 값을 제공할 수 있다.
pointerType을 사용하는 방법의 기본적인 예는
예제 2를 참조한다. 또한 개발자는 자체 사용자 정의
pointerType 값을 구현했을 수 있는 사용자 에이전트와
pointerType이 단순히 빈 문자열인 상황을 처리할 수 있도록
어떤 형태로든 기본 처리를 포함해야 한다.
isPrimary포인터가 이 포인터 유형의 주 포인터를 나타내는지 여부를 나타낸다.
persistentDeviceId포인팅 장치의 고유 식별자. 하드웨어가 여러 포인터를 지원하는 경우,
포인팅 장치에서 생성된 포인터 이벤트는 해당 포인터를 세션 전체에서 고유하게 식별할 수 있는
경우에만 persistentDeviceId를 가져야 한다.
포인터를 고유하게 식별할 수 있는 경우 해당 포인팅 장치에 할당된
persistentDeviceId는 세션의 나머지 기간 동안 일정하게 유지된다.
persistentDeviceId 값 0은 이벤트를 생성한 장치를
식별할 수 없는 경우를 나타내기 위해 예약하고 사용해야 한다. pointerId와 마찬가지로 서로 다른
페이지나 도메인에 걸친 핑거프린팅 및 추적 가능성을 최소화하기 위해
persistentDeviceId는 페이지/세션의 수명 동안에만 해당 특정 포인팅 장치와
명시적으로 연결해야 하며, 해당 특정 포인팅 장치를 새 세션에서
다시 사용할 때는 새로 무작위화된 persistentDeviceId를 선택해야 한다.
persistentDeviceId를 사용할 수 있다고 보장되지는 않는다.
예를 들어 장치가 pointerdown에
persistentDeviceId가 포함될 수 있을 만큼 제때 하드웨어 ID를
디지타이저에 보고하지 않을 수 있다. 이런 경우 persistentDeviceId는
처음에는 0이었다가 유효한 값으로 변경될 수 있다.
getCoalescedEvents()병합된 이벤트 목록을 반환하는 메서드.
getPredictedEvents()예측된 이벤트 목록을 반환하는 메서드.
PointerEventInit 딕셔너리는 PointerEvent 인터페이스의 생성자가
신뢰할 수 없는(합성) 포인터 이벤트를 구성할 수 있는 메커니즘을 제공하는 데 사용된다.
이 딕셔너리는 MouseEventInit 딕셔너리를
상속한다.
신뢰할 수 없는 포인터 이벤트를 발생시키는 방법을 보여 주는 샘플 코드는 예제를 참조한다.
PointerEvent의 이벤트
구성 단계는 PointerEventInit의 coalescedEvents를 병합된 이벤트 목록으로 복제하고,
PointerEventInit의 predictedEvents를 예측된 이벤트 목록으로 복제한다.
PointerEvent 인터페이스는 MouseEvent를 상속한다.
또한 CSSOM View Module에서 제안된
확장에 유의한다. 이 확장은 분수 좌표를 허용하기 위해 여러 좌표 속성을
long에서 double로 변경한다. 이 제안된 확장을
PointerEvent에는 이미 구현했지만 일반
MouseEvent에는 구현하지 않은
사용자 에이전트에는 click,
auxclick,
및 contextmenu 이벤트와 관련하여 추가 요구사항이 있다.
다중 포인터(예: 멀티터치) 시나리오에서 isPrimary 속성은
각 포인터 유형의 활성 포인터 집합 중
주 포인터를 식별하는 데 사용된다.
pointerType당 하나)가 주 포인터로 간주된다. 예를 들어 터치 접촉과
마우스 커서를 동시에 움직이면 둘 다 주 포인터로 간주되는 포인터가 생성된다.
isPrimary 값이
false인 포인터 이벤트를 발생시킬 수 있다.
e라는 이름의 포인터 이벤트를 발생시킨다는 것은
e라는 이름의
이벤트를
발생시키는 것을 의미하며, 이때 PointerEvent를 사용하고 그 속성은
PointerEvent 인터페이스 및
속성 및 기본 동작에 정의된 대로 설정한다.
이벤트가 gotpointercapture, lostpointercapture,
click,
auxclick 또는 contextmenu 이벤트가 아닌 경우 이
PointerEvent에 대해 대기 중인 포인터 캡처 처리 단계를
실행한다.
이벤트가 발생하는 대상을 결정하는 방법은 다음과 같다:
targetDocument를 대상의 노드 문서로 둔다 [DOM].
이벤트가 pointerdown, pointermove 또는 pointerup인 경우 이벤트의 pointerId에 대한 활성 문서를 targetDocument로 설정한다.
이벤트가 pointerdown이고, 연결된
장치가 직접 조작 장치이며 대상이 Element인 경우,
암시적 포인터 캡처에 설명된 대로 이 pointerId의 포인터 캡처를 설정하여 대상 요소를 가리키게 한다.
이 이벤트를 발생시키기 전에 사용자
에이전트는 이벤트 순서를 보장하기 위해 포인팅 장치가
previousTarget에서 대상으로 이동한 것처럼 대상을 처리하는 것이 좋다.
needsOverEvent 플래그가 설정되어 있으면 대상 요소가
동일하더라도 pointerover 이벤트가 필요하다.
결정된 대상에 이벤트를 발생시킨다.
결정된 대상을 주어진 포인터의 previousTarget으로 저장하고,
needsOverEvent 플래그를 false로 재설정한다.
어느 시점에서든 previousTarget이 더 이상 연결된 상태가 아니게 되면 [DOM],
previousTarget에 이벤트를 디스패치하는 것에 해당하는 이벤트 경로를 따라
가장 가까운 여전히 연결된 [DOM] 부모로
previousTarget을 갱신하고 needsOverEvent 플래그를 true로 설정한다.
이 명세에서 정의된 이벤트 유형의 bubbles 및 cancelable 속성과
기본 동작은 다음 표에 나와 있다. 각 이벤트 유형에 대한 자세한 내용은 포인터 이벤트 유형에서 제공한다.
| 이벤트 유형 | 버블링 | 취소 가능 | 기본 동작 |
|---|---|---|---|
pointerover
|
예 | 예 | 없음 |
pointerenter |
아니요 | 아니요 | 없음 |
pointerdown
|
예 | 예 | 상황에 따라 다름: 포인터가 주 포인터인 경우
mousedown 이벤트의 모든 기본 동작
이 이벤트를 취소하면 이후 호환성 마우스 이벤트의 발생도 방지된다. |
pointermove
|
예 | 예 | 상황에 따라 다름: 포인터가 주 포인터인 경우 mousemove의 모든 기본 동작
|
pointerrawupdate |
예 | 아니요 | 없음 |
pointerup |
예 | 예 | 상황에 따라 다름: 포인터가 주 포인터인 경우 mouseup의 모든 기본 동작
|
pointercancel |
예 | 아니요 | 없음 |
pointerout
|
예 | 예 | 없음 |
pointerleave |
아니요 | 아니요 | 없음 |
gotpointercapture |
예 | 아니요 | 없음 |
lostpointercapture |
예 | 아니요 | 없음 |
일반적으로 직접 조작 상호작용의 결과인 뷰포트 조작
(패닝 및 확대/축소)은 의도적으로 포인터 이벤트의 기본 동작이 아니다. 이는 이러한 동작
(예: 터치스크린에서 손가락을 움직여 페이지를 패닝하는 동작)을 포인터 이벤트를 취소하여
억제할 수 없음을 의미한다. 저자는 대신 touch-action을 사용하여 문서의 특정 영역에 대한
직접 조작 동작을 선언해야 한다.
이벤트 취소에 대한 이러한 의존성을 제거하면 사용자 에이전트가 성능을 최적화하기 쉬워진다.
pointerenter 및 pointerleave 이벤트의 경우 composed
[DOM]
속성은 false인 것이 좋고, 위 표의 다른 모든 포인터 이벤트에 대해서는 이 속성이
true인 것이 좋다.
위 표의 모든 포인터 이벤트에 대해 detail 속성은
0인 것이 좋다.
fromElement 및 toElement를 노출한다.
저자가 표준화된 대안(target 및 relatedTarget)을 사용하도록
전환하기 위해 이러한 사용자 에이전트가 PointerEvents에서 해당 (상속된) 속성의 값을
null로 설정할 것을 권장한다.
MouseEvent relatedTarget과 유사하게,
relatedTarget은 포인터가 방금 경계를 벗어난 요소(pointerover 또는
pointerenter 이벤트의 경우) 또는 포인터가 경계 안으로 들어가는 요소
(pointerout 또는 pointerleave 이벤트의 경우)로 초기화해야 한다.
다른 포인터 이벤트에서는 이 값의 기본값이 null이다. 요소가 포인터 캡처를 받으면
해당 포인터의 이후 모든 이벤트가 캡처 요소의 경계 내부에 있는 것으로 간주됨에 유의한다.
gotpointercapture
및 lostpointercapture 이벤트의 경우,
위 표에서 정의된 속성을 제외한 모든 속성은 사용자 에이전트가 대기 중인 포인터 캡처 처리 단계를
실행하고 gotpointercapture
및 lostpointercapture 이벤트를 발생시키게 한
Pointer Event와 동일해야 한다.
사용자 에이전트는
포인터 캡처를 암시적으로
해제할 때뿐만 아니라 gotpointercapture 또는 lostpointercapture가 아닌
Pointer Events를 발생시킬 때도 다음 단계를 실행해야 한다.
lostpointercapture라는 이름의
포인터 이벤트를 포인터 캡처 대상
재정의
노드에서 발생시킨다.
gotpointercapture라는 이름의
포인터 이벤트를 대기 중인
포인터 캡처 대상 재정의에서 발생시킨다.
click,
auxclick 및 contextmenu 이벤트에 대한 섹션에 정의된 대로,
lostpointercapture 이벤트가
이미 디스패치된 후에도 해당 click, auxclick 또는
contextmenu 이벤트가 있다면 여전히 캡처 대상으로 디스패치된다.
사용자 에이전트는
웹 페이지가 특정 pointerId를 가진 포인터 이벤트를
계속 수신할 가능성이 낮다고 감지하면 포인터 이벤트 스트림을
억제해야 한다. 다음 시나리오 중 하나라도 이 조건을 충족한다
(추가 시나리오가 있을 수 있다):
touch-action CSS
속성에 대한 섹션을 참조한다.
사용자 에이전트가 포인터 이벤트 스트림을 억제할 수 있는 다른 시나리오는 다음과 같다:
이러한 시나리오를 감지하는 방법은 이 명세의 범위를 벗어난다.
사용자 에이전트는 포인터 이벤트 스트림을 억제하기 위해 다음 단계를 실행해야 한다:
pointercancel
이벤트를 발생시킨다.pointerout 이벤트를
발생시킨다.
pointerleave 이벤트를
발생시킨다.
화면 표면을 기준으로 이동했거나 속성 중 하나라도 변화한 포인팅 장치는 포인터 이벤트 유형에 정의된
여러 이벤트를 발생시킨다. 정지한 포인팅 장치(화면 표면을 기준으로 이동하지도 않았고
어떤 속성도 변화하지 않은 장치)의 경우 사용자
에이전트는 포인터의
히트
테스트 대상에
영향을 준 레이아웃 변경 후 특정 경계 이벤트를 발생시켜야 한다.
자세한 내용은 pointerover, pointerenter, pointerout 및 pointerleave를 참조한다. 사용자 에이전트는
성능상의 이유(예: 지나치게 많은 히트 테스트 또는 경계 이벤트 리스너로 인한 레이아웃 변경을
방지하기 위해) 이러한 경계 이벤트의 발생을 지연할 수 있다.
pointermove 이벤트를 발생시키지
않는다.Pointer Events에는 X-Y 평면을 기준으로 트랜스듀서의 방향을 표현하기 위한 상호 보완적인
두 속성 집합, 즉 tiltX / tiltY(원래 Pointer Events 명세에 도입됨)와
azimuthAngle / altitudeAngle(Touch Events - Level 2
명세에서 채택됨)이 포함된다.
특정 하드웨어 및 플랫폼에 따라 사용자 에이전트는 화면 평면을 기준으로 한 트랜스듀서 방향에 대해
tiltX / tiltY 또는 altitudeAngle /
azimuthAngle 중 하나의 값 집합만 받을 가능성이 높다. 사용자 에이전트는
이러한 값을 변환할 때 다음 알고리즘을 사용해야 한다.
사용자 에이전트가 azimuthAngle / altitudeAngle에서
tiltX / tiltY를 계산할 때 최종 정수 값은 Math.round [ECMASCRIPT] 규칙을 사용하여 반올림하는 것이
좋다.
/* tiltX/tiltY와 altitudeAngle/azimuthAngle 간 변환 */
function spherical2tilt(altitudeAngle, azimuthAngle) {
const radToDeg = 180/Math.PI;
let tiltXrad = 0;
let tiltYrad = 0;
if (altitudeAngle == 0) {
// 펜이 X-Y 평면에 있다
if (azimuthAngle == 0 || azimuthAngle == 2*Math.PI) {
// 펜이 양의 X축에 있다
tiltXrad = Math.PI/2;
}
if (azimuthAngle == Math.PI/2) {
// 펜이 양의 Y축에 있다
tiltYrad = Math.PI/2;
}
if (azimuthAngle == Math.PI) {
// 펜이 음의 X축에 있다
tiltXrad = -Math.PI/2;
}
if (azimuthAngle == 3*Math.PI/2) {
// 펜이 음의 Y축에 있다
tiltYrad = -Math.PI/2;
}
if (azimuthAngle>0 && azimuthAngle<Math.PI/2) {
tiltXrad = Math.PI/2;
tiltYrad = Math.PI/2;
}
if (azimuthAngle>Math.PI/2 && azimuthAngle<Math.PI) {
tiltXrad = -Math.PI/2;
tiltYrad = Math.PI/2;
}
if (azimuthAngle>Math.PI && azimuthAngle<3*Math.PI/2) {
tiltXrad = -Math.PI/2;
tiltYrad = -Math.PI/2;
}
if (azimuthAngle>3*Math.PI/2 && azimuthAngle<2*Math.PI) {
tiltXrad = Math.PI/2;
tiltYrad = -Math.PI/2;
}
}
if (altitudeAngle != 0) {
const tanAlt = Math.tan(altitudeAngle);
tiltXrad = Math.atan(Math.cos(azimuthAngle) / tanAlt);
tiltYrad = Math.atan(Math.sin(azimuthAngle) / tanAlt);
}
return {"tiltX":tiltXrad*radToDeg, "tiltY":tiltYrad*radToDeg};
}
function tilt2spherical(tiltX, tiltY) {
const tiltXrad = tiltX * Math.PI/180;
const tiltYrad = tiltY * Math.PI/180;
// 방위각 계산
let azimuthAngle = 0;
if (tiltX == 0) {
if (tiltY > 0) {
azimuthAngle = Math.PI/2;
}
else if (tiltY < 0) {
azimuthAngle = 3*Math.PI/2;
}
} else if (tiltY == 0) {
if (tiltX < 0) {
azimuthAngle = Math.PI;
}
} else if (Math.abs(tiltX) == 90 || Math.abs(tiltY) == 90) {
// 방위각을 계산하기에 정보가 충분하지 않음
azimuthAngle = 0;
} else {
// 경계가 아닌 경우: tiltX와 tiltY 모두 0 또는 +-90이 아님
const tanX = Math.tan(tiltXrad);
const tanY = Math.tan(tiltYrad);
azimuthAngle = Math.atan2(tanY, tanX);
if (azimuthAngle < 0) {
azimuthAngle += 2*Math.PI;
}
}
// 고도각 계산
let altitudeAngle = 0;
if (Math.abs(tiltX) == 90 || Math.abs(tiltY) == 90) {
altitudeAngle = 0
} else if (tiltX == 0) {
altitudeAngle = Math.PI/2 - Math.abs(tiltYrad);
} else if (tiltY == 0) {
altitudeAngle = Math.PI/2 - Math.abs(tiltXrad);
} else {
// 경계가 아닌 경우: tiltX와 tiltY 모두 0 또는 +-90이 아님
altitudeAngle = Math.atan(1.0/Math.sqrt(Math.pow(Math.tan(tiltXrad),2) + Math.pow(Math.tan(tiltYrad),2)));
}
return {"altitudeAngle":altitudeAngle, "azimuthAngle":azimuthAngle};
}
PointerEvent 초기화event, eventType 및 eventTarget, bubbles, 그리고 cancelable로 PointerEvent를 초기화하려면 다음 단계를 실행한다:
PointerEvent 값으로
초기화한다.PointerEvent 생성
eventType 및 eventTarget,
bubbles, 그리고 cancelable로
PointerEvent를 생성하려면 다음 단계를 실행한다:
PointerEvent를 사용하여
이벤트를
생성한 결과로 둔다
DOMString으로 둔다MouseEvent로 둔다PointerEvent를 사용하여
이벤트를
생성한 결과로 둔다
target으로 둔다MouseEvent 속성을
mouseevent에서 event로 복사한다
MouseEvent로 둔다TODO.
target으로 둔다MouseEvent로 둔다TODO.
target으로 둔다MouseEvent로 둔다TODO.
target으로 둔다MouseEvent로 둔다TODO.
target으로 둔다MouseEvent로 둔다
이것이 pointermove와 pointerrawupdate를 전송할 수 있는가? 아니면 메서드가 2개 필요한가?
pointermove 이벤트가 병합되는 방식을 올바르게 정의하려면 무엇이 필요한가?
TODO.
target으로 둔다MouseEvent로 둔다
mousedown 이벤트와 달리 여러 버튼이 눌렸을 때 pointerdown
이벤트는 중첩되지 않는다.
필드를 PointerEvent로 복사할 수 있도록 MouseEvent가
전달된다.
TODO.
target으로 둔다MouseEvent로 둔다
target으로 둔다MouseEvent로 둔다
mouseup 이벤트와 달리 여러 버튼이 눌렸을 때 pointerup 이벤트는 중첩되지 않는다.
필드를 PointerEvent로 복사할 수 있도록 MouseEvent가 전달된다.
TODO.
target으로 둔다다음은 이 명세에서 정의하는 이벤트 유형이다.
주 포인터의 경우 이러한 이벤트(gotpointercapture 및 lostpointercapture 제외)는 호환성 마우스 이벤트도 발생시킬 수 있다.
| 유형 | pointerover |
|---|---|
| 인터페이스 | PointerEvent
|
| 버블링 | 예 |
| 취소 가능 | 예 |
| 합성 | 예 |
| 컨텍스트 (신뢰할 수 있는 이벤트) |
|
사용자 에이전트는 다음 중 하나가 발생하면
포인터 이벤트를 발생시켜
pointerover라고 명명해야 한다:
pointerdown 이벤트를 호버를 지원하지 않는 장치에 대해
발생시키기 전(pointerdown 참조).| 유형 | pointerenter |
|---|---|
| 인터페이스 | PointerEvent
|
| 버블링 | 아니요 |
| 취소 가능 | 아니요 |
| 합성 | 아니요 |
| 컨텍스트 (신뢰할 수 있는 이벤트) |
|
사용자 에이전트는 다음 중 하나가 발생하면
포인터 이벤트를 발생시켜
pointerenter라고 명명해야
한다:
pointerdown 이벤트를 호버를 지원하지 않는 장치에 대해
발생시키기 전(pointerdown 참조).| 유형 | pointerdown |
|---|---|
| 인터페이스 | PointerEvent
|
| 버블링 | 예 |
| 취소 가능 | 예 |
| 합성 | 예 |
| 컨텍스트 (신뢰할 수 있는 이벤트) |
포인터가 활성 버튼 상태에 들어가면 사용자 에이전트는
포인터 이벤트를 발생시켜
pointerdown이라고 명명해야
한다. 마우스의 경우 이는 장치가 눌린 버튼이 없는 상태에서
하나 이상의 버튼이 눌린 상태로 전환될 때이다. 터치의 경우 디지타이저와
물리적으로 접촉할 때이다. 펜의 경우 아무 버튼도 눌리지 않은 상태에서 펜이 디지타이저와
물리적으로 접촉하거나, 호버 중에 아무 버튼도 눌리지 않은 상태에서 하나 이상의 버튼이
눌린 상태로 전환될 때이다.
pointerdown 및 pointerup이 mousedown 및
mouseup과 동일한 모든 상황에서 발생하는 것은 아니라는 의미이다. 자세한 내용은 동시 버튼을 참조한다.
호버를 지원하지 않는 입력 장치의 경우
사용자
에이전트는 pointerdown 이벤트를
디스패치하기 전에 포인터
이벤트를 발생시켜 pointerover라고 명명한 뒤,
이어서 pointerenter라고 명명한
포인터 이벤트를 발생시켜야 한다.
pointerdown 이벤트를 취소하여
(isPrimary 속성이 true인 경우) 방지할 수 있다. 이렇게 하면
포인터에 PREVENT MOUSE EVENT 플래그가 설정된다. 그러나 이것이
mouseover, mouseenter, mouseout 또는
mouseleave 이벤트의 발생을 방지하지는 않는다는 점에 유의한다.
| 유형 | pointermove |
|---|---|
| 인터페이스 | PointerEvent
|
| 버블링 | 예 |
| 취소 가능 | 예 |
| 합성 | 예 |
| 컨텍스트 (신뢰할 수 있는 이벤트) |
포인터에서 pointerdown 또는 pointerup 이벤트를 발생시키지 않는 속성이 변경되면
사용자 에이전트는
포인터 이벤트를 발생시켜
pointermove라고 명명해야 한다.
여기에는 좌표, 압력, 접선 압력,
기울기, 비틀림, 접촉 형상(width 및 height) 또는 동시 버튼의 변경이 포함된다.
사용자 에이전트는 pointermove 이벤트의 디스패치를
(예: 성능상의 이유로) 지연할 수 있다.
병합된 이벤트 정보는 디스패치된 단일 pointermove 이벤트에 대해 getCoalescedEvents 메서드를
통해 노출된다.
이러한 이벤트의 최종 좌표를 이벤트의 대상을 찾는 데 사용해야 한다.
| 유형 | pointerrawupdate |
|---|---|
| 인터페이스 | PointerEvent
|
| 버블링 | 예 |
| 취소 가능 | 아니요 |
| 합성 | 예 |
| 컨텍스트 (신뢰할 수 있는 이벤트) |
포인터에서 pointerdown 또는 pointerup 이벤트를 발생시키지 않는
속성이 변경되면 사용자 에이전트는
포인터 이벤트를 발생시켜
pointerrawupdate라고
명명해야 하며, 보안 컨텍스트
내에서만 그렇게 해야 한다. 이러한 속성의 목록은 pointermove 이벤트를 참조한다.
pointermove와 달리,
사용자 에이전트는 pointerrawupdate 이벤트를
가능한 한 빨리,
JavaScript가 이벤트를 처리할 수 있는 만큼 자주 디스패치하는 것이 좋다.
pointerrawupdate 이벤트의 target은
pointermove 이벤트와 다를 수 있다.
이는 pointermove 이벤트가
지연되거나 병합될 수 있고, target을 찾는 데 사용되는 이벤트의 최종 위치가
병합된 이벤트와 다를 수 있기 때문이다.
아직 이벤트 루프에서
디스패치되지 않은 동일한 pointerId를 가진 다른 pointerrawupdate가 이미 있는 경우,
사용자 에이전트는 새 pointerrawupdate를 새 태스크를
생성하는 대신 해당 이벤트와 병합할 수 있다.
이로 인해 pointerrawupdate에
병합된 이벤트가 포함될 수 있으며,
이벤트가 이벤트 루프에서
처리되는 즉시 모두 하나의 pointerrawupdate 이벤트의
병합된 이벤트로 전달된다.
자세한 내용은 getCoalescedEvents를 참조한다.
pointerrawupdate와 pointermove의 순서와 관련하여,
사용자 에이전트가 플랫폼으로부터 pointerrawupdate 및 pointermove 이벤트를 모두 발생시키는
업데이트를 수신한 경우, 사용자 에이전트는
해당
pointermove보다 먼저
pointerrawupdate 이벤트를
디스패치해야 한다.
target을 제외하면 마지막 pointermove 이벤트 이후
디스패치된 모든 pointerrawupdate 이벤트의
병합된 이벤트
목록을 연결한 것은 다른 이벤트 속성 측면에서 다음 pointermove 이벤트의 병합된 이벤트와
동일하다.
pointerrawupdate의
속성은 대부분 pointermove와 동일하지만,
pointerrawupdate에서는
cancelable이 반드시 false여야 한다는 점이 다르다.
사용자 에이전트는 pointerrawupdate에 대해
호환성 마우스 이벤트를 발생시키지 않는 것이 좋다.
pointerrawupdate
이벤트에 리스너를
추가하면 사용자 에이전트의 구현에 따라 웹 페이지 성능에 부정적인 영향을 줄 수 있다.
대부분의 사용 사례에서는 다른 pointerevent 유형으로 충분하다.
JavaScript가 고주파 이벤트를 필요로 하고 이를 그만큼 빠르게 처리할 수 있는 경우에만 pointerrawupdate
리스너를 추가해야 한다.
이러한 경우 다른 유형의 포인터 이벤트를 수신할 필요는 없을 가능성이 높다.| 유형 | pointerup |
|---|---|
| 인터페이스 | PointerEvent
|
| 버블링 | 예 |
| 취소 가능 | 예 |
| 합성 | 예 |
| 컨텍스트 (신뢰할 수 있는 이벤트) |
포인터가 활성 버튼 상태를 벗어나면 사용자 에이전트는
포인터 이벤트를 발생시켜
pointerup이라고 명명해야 한다.
마우스의 경우 이는 장치가 하나 이상의 버튼이 눌린 상태에서
눌린 버튼이 없는 상태로 전환될 때이다. 터치의 경우 디지타이저와의
물리적 접촉이 제거될 때이다. 펜의 경우 아무 버튼도 눌리지 않은 상태에서 펜이 디지타이저와의
물리적 접촉에서 떨어지거나, 호버 중에 하나 이상의 버튼이 눌린 상태에서 눌린 버튼이 없는
상태로 전환될 때이다.
호버를 지원하지 않는 입력 장치의 경우,
사용자
에이전트는 pointerup 이벤트를 디스패치한 후
포인터 이벤트를
발생시켜 pointerout이라고 명명한 뒤,
이어서 pointerleave라고 명명한
포인터 이벤트를 발생시켜야 한다.
모든 pointerup 이벤트의 pressure
값은 0이다.
포인터가 현재 캡처되어 있다면 사용자 에이전트는 또한 포인터 캡처를 암시적으로 해제해야 한다.
pointerdown 및 pointerup이 mousedown 및
mouseup과 동일한 모든 상황에서 발생하는 것은 아니라는 의미이다. 자세한 내용은 동시 버튼을 참조한다.
| 유형 | pointercancel |
|---|---|
| 인터페이스 | PointerEvent
|
| 버블링 | 예 |
| 취소 가능 | 아니요 |
| 합성 | 예 |
| 컨텍스트 (신뢰할 수 있는 이벤트) |
사용자 에이전트는
포인터 이벤트 스트림을 억제해야 하는
시나리오를 감지하면 포인터 이벤트를 발생시켜
pointercancel이라고 명명해야
한다.
pointercancel 이벤트의 다음 속성 값은
동일한 pointerId를 가진 마지막으로
디스패치된 포인터 이벤트의 값과 일치해야 한다: width,
height, pressure, tangentialPressure, tiltX,
tiltY, twist, altitudeAngle, azimuthAngle,
pointerType, isPrimary, 그리고 Mouse Events에서 상속된 좌표.
pointercancel 이벤트의
coalescedEvents 및 predictedEvents 목록은 비어 있어야 하며,
이벤트의 cancelable 속성은
반드시 false여야 한다.
| 유형 | pointerout |
|---|---|
| 인터페이스 | PointerEvent
|
| 버블링 | 예 |
| 취소 가능 | 예 |
| 합성 | 예 |
| 컨텍스트 (신뢰할 수 있는 이벤트) |
|
사용자 에이전트는
다음 중 하나가 발생하면 포인터 이벤트를 발생시켜
pointerout이라고 명명해야 한다:
pointerup 이벤트를
발생시킨 후(pointerup 참조).| 유형 | pointerleave |
|---|---|
| 인터페이스 | PointerEvent
|
| 버블링 | 아니요 |
| 취소 가능 | 아니요 |
| 합성 | 아니요 |
| 컨텍스트 (신뢰할 수 있는 이벤트) |
|
사용자 에이전트는
다음 중 하나가 발생하면 포인터 이벤트를 발생시켜
pointerleave라고 명명해야
한다:
pointerup 이벤트를
발생시킨 후(pointerup 참조).| 유형 | gotpointercapture |
|---|---|
| 인터페이스 | PointerEvent
|
| 버블링 | 예 |
| 취소 가능 | 아니요 |
| 합성 | 예 |
| 컨텍스트 (신뢰할 수 있는 이벤트) |
요소가 포인터 캡처를 받으면 사용자
에이전트는 포인터 이벤트를 발생시켜 gotpointercapture라고
명명해야 한다. 이 이벤트는 포인터 캡처를 받는 요소에서 발생한다.
이후 해당 포인터의 이벤트는 이 요소에서 발생한다. 포인터 캡처 설정 및 대기 중인 포인터 캡처 처리 섹션을 참조한다.
| 유형 | lostpointercapture |
|---|---|
| 인터페이스 | PointerEvent
|
| 버블링 | 예 |
| 취소 가능 | 아니요 |
| 합성 | 예 |
| 컨텍스트 (신뢰할 수 있는 이벤트) |
포인터의 포인터 캡처가 해제된 후 사용자
에이전트는 포인터 이벤트를 발생시켜 lostpointercapture라고
명명해야 한다. 이 이벤트는 캡처가 해제된 후 해당 포인터의
후속 이벤트보다 먼저 발생해야 한다. 이 이벤트는 포인터 캡처가 제거된
요소에서 발생한다. click, auxclick 및
contextmenu 이벤트를 제외한 해당 포인터의 모든 후속 이벤트는 이벤트 대상을
결정하기 위해 일반적인 히트 테스트 메커니즘(이 명세의 범위를 벗어남)을 따른다. 포인터
캡처 해제, 포인터 캡처의
암시적 해제 및 대기 중인 포인터
캡처 처리 섹션을 참조한다.
다음 섹션에서는 포인터 캡처의 설정 및 해제를 용이하게 하기 위한 기존 Element 인터페이스의
확장을 설명한다.
WebIDLpartial interface Element {
undefined setPointerCapture (long pointerId);
undefined releasePointerCapture (long pointerId);
boolean hasPointerCapture (long pointerId);
};
setPointerCapture()인수 pointerId로 식별되는 포인터의
포인터 캡처를 설정하여 이 메서드가 호출된
요소를 가리키게 한다. 포인터의 후속 이벤트에서는 포인터가 항상 캡처 대상 위에 있는 것처럼
캡처 대상이 일반적인 히트 테스트 결과를 대신하며, 캡처가 해제될 때까지 이러한 이벤트는 항상
이 요소를 대상으로 해야 한다. 이 메서드가 효과를 가지려면 포인터가
활성 버튼 상태에 있어야 하며, 그렇지
않으면 아무 알림 없이 실패한다. 제공된 메서드의 인수가
활성 포인터 중 어느 것과도 일치하지 않으면
"NotFoundError"
DOMException을
발생시킨다.
releasePointerCapture()인수 pointerId로
식별되는 포인터의 포인터 캡처를 해제하여 이 메서드가 호출된
요소에서 제거한다. 포인터의 후속 이벤트는 이벤트 대상을 결정하기 위해 일반적인 히트 테스트
메커니즘(이 명세의 범위를 벗어남)을 따른다. 제공된 메서드의 인수가 활성 포인터 중 어느 것과도 일치하지 않으면
"NotFoundError"
DOMException을
발생시킨다.
hasPointerCapture이 메서드가 호출된 요소가 인수 pointerId로 식별되는 포인터에
대해 포인터
캡처를 보유하고 있는지 나타낸다. 특히 대기 중인 포인터 캡처 대상
재정의가 pointerId에
대해 이 메서드가 호출된 요소로 설정되어 있으면 true를 반환하고,
그렇지 않으면 false를 반환한다.
setPointerCapture()를
호출한 직후 해당 요소가 아직 gotpointercapture 이벤트를
받지 않았더라도 true를 반환한다. 따라서 pointerdown 이벤트 리스너 내부에서
암시적 포인터 캡처를 감지하는 데
유용할 수 있다.
다음 섹션에서는 이벤트 핸들러 등록을 용이하게 하기 위한 기존 GlobalEventHandlers
믹스인의 확장을 설명한다.
WebIDLpartial interface mixin GlobalEventHandlers {
attribute EventHandler onpointerover;
attribute EventHandler onpointerenter;
attribute EventHandler onpointerdown;
attribute EventHandler onpointermove;
[SecureContext] attribute EventHandler onpointerrawupdate;
attribute EventHandler onpointerup;
attribute EventHandler onpointercancel;
attribute EventHandler onpointerout;
attribute EventHandler onpointerleave;
attribute EventHandler ongotpointercapture;
attribute EventHandler onlostpointercapture;
};
onpointeroverpointerover 이벤트 유형의 이벤트
핸들러 IDL 속성.
onpointerenterpointerenter 이벤트 유형의 이벤트
핸들러 IDL 속성.
onpointerdownpointerdown 이벤트 유형의 이벤트
핸들러 IDL 속성.
onpointermovepointermove 이벤트 유형의 이벤트
핸들러 IDL 속성.
onpointerrawupdatepointerrawupdate 이벤트 유형의 이벤트
핸들러 IDL 속성.
onpointeruppointerup 이벤트 유형의 이벤트
핸들러 IDL 속성.
onpointercancelpointercancel 이벤트 유형의 이벤트
핸들러 IDL 속성.
onpointeroutpointerout 이벤트 유형의 이벤트
핸들러 IDL 속성.
onpointerleavepointerleave 이벤트 유형의 이벤트
핸들러 IDL 속성.
ongotpointercapturegotpointercapture 이벤트
유형의 이벤트
핸들러 IDL 속성.
onlostpointercapturelostpointercapture
이벤트 유형의 이벤트
핸들러 IDL 속성.
속성 및 기본 동작에서 언급했듯이 뷰포트
조작(패닝 및 확대/축소)은 포인터 이벤트를 취소하여 억제할 수 없다. 대신 저자는
touch-action CSS 속성을 사용하여 이러한 동작 중 어떤 것을 허용하고
어떤 것을 억제할지 선언적으로 정의해야 한다.
touch-action CSS 속성은
터치 입력만을 가리키는 것처럼 보이지만, 실제로는 패닝 및 확대/축소를 위한 직접 조작을 허용하는 모든 형태의 포인터 입력에 적용된다.
| 이름: | touch-action |
|---|---|
| 값: | auto | none | [ [ pan-x | pan-left |
pan-right ] || [ pan-y | pan-up |
pan-down ] ] | manipulation
|
| 초깃값: | auto |
| 적용 대상: | 대체되지 않은 인라인 요소, 테이블 행, 행 그룹, 테이블 열, 열 그룹을 제외한 모든 요소 |
| 상속: | 아니요 |
| 백분율: | 해당 없음 |
| 미디어: | 시각적 |
| 계산값: | 지정된 값과 동일 |
| 정규 순서: | 문법에 따름 |
| 애니메이션 유형: | 애니메이션 불가 |
touch-action CSS 속성은 직접
조작 상호작용(속성 이름과 달리 터치에만 한정되지 않음)이 사용자 에이전트의
패닝 및 확대/축소 동작을 트리거할 수 있는지 결정한다. touch-action 값에 대한 섹션을 참조한다.
패닝 또는 확대/축소를 시작하기 직전에 다음 조건이 모두 참이면 사용자 에이전트는 포인터 이벤트 스트림을 억제해야 한다:
pointerdown 이벤트가 전송되었으며,pointerup 또는 pointercancel 이벤트(위에서 언급한 pointerdown 이후)가 아직 전송되지 않았다.touch-action은 임베드된 브라우징 컨텍스트까지 적용되거나 캐스케이드되지 않는다.
예를 들어 <iframe>에 touch-action을 적용하더라도
<iframe> 자체 내부에서 패닝 및 확대/축소를 위한 직접 조작 상호작용의
동작에는 영향을 주지 않는다.
사용자가 직접 조작 포인터
(예: 터치스크린의 터치 또는 스타일러스)를 사용하여 요소와 상호작용할 때 해당 입력의 효과는
touch-action 속성 값과 요소 및 그 조상의 기본 직접 조작 동작에 따라
다음과 같이 결정된다:
touch-action을 준수한다. CSS 변환이 적용된 경우
요소의 좌표 공간은 여기서의 준수 여부에 영향을 주는 방식으로 화면 좌표와 다를 수 있음에 유의한다.
예를 들어 화면에 대해 90도 회전된 요소의 X축은 화면 좌표의 Y축과 평행하다.touch-action 속성을 준수하는 경우 지원된다.
document 요소 사이의 각 요소에 대한 touch-action 속성을 준수하는 경우 지원된다.
touch-action 값의
모든 변경을 해당 동작이 지속되는 동안 무시한다. 예를 들어 pointerdown 핸들러 스크립트의 일부로 요소의
touch-action 값을 auto에서 none으로 프로그래밍 방식으로
변경해도 해당 포인터가 활성 상태인 동안 사용자 에이전트가 해당 입력의 패닝 또는 확대/축소
동작을 중단하거나 억제하지 않는다.
pan-* touch-action 값의 경우 사용자 에이전트가
제스처 시작 시 제스처를 직접 처리할지 여부를 결정한 후에는 동일한 제스처의 방향이 이후에
변경되어도 해당 포인터가 활성 상태인 동안 사용자 에이전트는 이를 무시하는 것이 좋다. 예를 들어 요소가
touch-action: pan-y로 설정되어 있고
(즉, 수직 패닝만 사용자 에이전트가 처리함) 터치 제스처가 수평 방향으로 시작된 경우,
손가락이 화면에 계속 닿아 있는 동안 사용자가 제스처 방향을 수직으로 변경하더라도
수직 패닝이 발생해서는 안 된다.
touch-action 값을 처리하거나
연관시키는 방법은 이 명세의 범위를 벗어난다.touch-action 속성은 뷰포트 패닝 및 확대/축소와 관련된 직접 조작 동작을 다룬다.
텍스트 선택/강조 또는 링크 및 폼 컨트롤 활성화와 같은 추가적인 사용자 에이전트 동작은
이 CSS 속성의 영향을 받아서는 안 된다.
auto나 none 값에 대한 동작을 트리거하는 상호작용이나 제스처를 정의하는 것은
이 명세의 범위를 벗어난다.pan-x 또는
pan-y)에는 패닝 중에 축을 변경할 수 없다.
touch-action 값은 [COMPAT]에 정의되어 있다.방향별 pan 값은 일부 오버스크롤 동작을 사용자 정의하는 데 유용하다.
예를 들어 간단한 당겨서 새로고침 효과를 구현하려면 문서의 스크롤 위치가
0일 때 문서의 touch-action을 pan-x pan-down으로 설정하고
그렇지 않을 때는 pan-x pan-y로 설정할 수 있다.
이를 통해 포인터 이벤트 핸들러가 문서의 맨 위에서 시작되는 위쪽 방향의 패닝/스크롤링
동작을 정의할 수 있다.
방향별 pan 값은 네이티브로 스크롤되는 요소 안에서 포인터 이벤트 처리로 사용자 정의
패닝을 구현하는 컴포넌트를 구성하는 데도 사용할 수 있다(또는 그 반대도 가능하다).
예를 들어 이미지 캐러셀은 pan-y를 사용하여 문서의 수직 패닝을 방해하지 않으면서
모든 수평 패닝 작업에 대한 포인터 이벤트를 수신하도록 할 수 있다.
캐러셀이 가장 오른쪽 끝에 도달하면 touch-action을
pan-y pan-right로 변경하여, 이후 범위를 넘어서는 스크롤 작업이 가능하다면
뷰포트 내에서 문서를 스크롤하도록 할 수 있다.
패닝/스크롤링 작업이 진행되는 동안에는 그 동작을 변경할 수 없다.
auto에서는 사용자 에이전트가
일반적으로 두 번 탭 제스처를 처리할 수 있도록 click 전에 300ms의 지연을 추가한다.
이러한 경우 touch-action: none 또는 touch-action: manipulation을
명시적으로 설정하면 이 지연이 제거된다. 탭 또는 두 번 탭 제스처를 결정하는 방법은
이 명세의 범위를 벗어남에 유의한다.
<div style="touch-action: none;">
이 요소는 그렇지 않으면 패닝 또는 확대/축소로 이어지는 모든 직접 조작 상호작용에 대한 포인터 이벤트를 수신한다.
</div>
<div style="touch-action: pan-x;">
이 요소는 수평 방향으로 패닝하지 않을 때 포인터 이벤트를 수신한다.
</div>
<div style="overflow: auto;">
<div style="touch-action: none;">
이 요소는 그렇지 않으면 패닝 또는 확대/축소로 이어지는 모든 직접 조작 상호작용에 대한 포인터 이벤트를 수신한다.
</div>
<div>
이 요소에서의 직접 조작 상호작용은 부모를 조작하는 데 사용될 수 있다.
</div>
</div>
<div style="overflow: auto;">
<div style="touch-action: pan-y;">
<div style="touch-action: pan-x;">
이 요소는 수평 패닝만 허용하지만 중간 조상
(이 요소와 스크롤 가능한 요소 사이)은 수직 패닝만 허용하므로
모든 직접 조작 상호작용에 대한 포인터 이벤트를 수신한다.
따라서 패닝/확대/축소를 위한 직접 조작 동작은
사용자 에이전트가 처리하지 않는다.
</div>
</div>
</div>
<div style="overflow: auto;">
<div style="touch-action: pan-y pan-left;">
<div style="touch-action: pan-x;">
이 요소는 왼쪽으로 패닝하지 않을 때 포인터 이벤트를 수신한다.
</div>
</div>
</div>
이 섹션은 비규범적이다.
포인터 캡처를 사용하면 특정 포인터의 이벤트(모든 호환성 마우스 이벤트 포함)를 포인터 위치의 일반적인
히트 테스트
결과가 아닌 특정 요소로 재지정할 수 있다.
이는 사용자 정의 슬라이더 컨트롤(예: [HTML]
<input type="range"> 컨트롤과 유사한 경우)과 같은 시나리오에서 유용하다. 포인터 캡처를
슬라이더 썸 요소에 설정하면 포인터가 썸에서 벗어나더라도 사용자가 컨트롤을 앞뒤로 슬라이드할 수 있다.
pointerdown이 발생한 후 포인터 캡처를
사용하면 포인터가 썸에서 벗어나더라도 사용자가 썸을 슬라이드할 수 있다.
포인터 캡처는 element.setPointerCapture(pointerId) 메서드를 호출하여
Element 유형의 element에 설정한다.
이 메서드가 호출되면 사용자 에이전트는 다음
단계를 실행해야 한다:
pointerId가 활성 포인터 중 어느 것과도 일치하지 않으면
"NotFoundError" DOMException을 발생시킨다.pointerId로 지정된
활성 포인터로 둔다.
InvalidStateError" DOMException을 발생시킨다.pointerLockElement)가
있는 동안 이 메서드가 호출되면 "InvalidStateError" DOMException을 발생시킨다.
pointerId에 대해 대기 중인 포인터 캡처 대상 재정의를 이 메서드가 호출된 Element로 설정한다.
pointerdown 리스너에서 해제하려는 시도가
실패한 경우에도 마찬가지이다.포인터 캡처는 element.releasePointerCapture(pointerId) 메서드를 호출하여 요소에서
명시적으로 해제한다. 이 메서드가 호출되면 사용자
에이전트는
다음 단계를 실행해야 한다:
pointerId가 활성 포인터 중 어느 것과도 일치하지 않고,
이 단계가 포인터 캡처의 암시적 해제의 결과로
호출된 것이 아니라면 "NotFoundError" DOMException을 발생시킨다.pointerId를 가진 Element에 대해 hasPointerCapture가 false이면, 이
단계를 종료한다.
pointerId에 대해 설정되어 있다면 대기 중인 포인터 캡처 대상
재정의를 지운다.패닝 및 확대/축소를 위한 직접 조작 상호작용을 구현하는 입력
(예: 터치스크린에서의 터치 또는 스타일러스)은 해야 한다. 마치 setPointerCapture가 임의의 pointerdown 리스너가 호출되기 직전에 대상 요소에서 호출된 것처럼
정확하게 동작해야 한다. hasPointerCapture API를 사용하여(예를
들어 pointerdown 리스너에서) 이것이
발생했는지 확인할 수 있다. 다음 포인터 이벤트가 발생하기 전에 해당 포인터에 대해 releasePointerCapture가
호출되지 않으면, gotpointercapture 이벤트가
대상에 (통상대로) 디스패치되어 캡처가 활성 상태임을 나타낸다.
pointerup 또는 pointercancel 이벤트를 발생시킨 직후
사용자 에이전트는
방금 디스패치된 pointerup 또는 pointercancel 이벤트의 pointerId에 대한 대기 중인 포인터 캡처 대상
재정의를 지우고, 필요한 경우 lostpointercapture를 발생시키도록
대기 중인 포인터 캡처 처리 단계를
실행해야 한다.
대기 중인 포인터 캡처 처리 단계를 실행한 후
포인터가 호버를 지원하면 사용자 에이전트는
캡처되지 않은 상태의
현재 포인터 위치를 반영하는 데 필요한 해당 경계 이벤트도 전송해야 한다.
포인터 캡처 대상 재정의가 더 이상 연결된 상태가 아니면 [DOM], 포인터 캡처 대상 재정의를 문서로 설정하는 것이 좋다.
대기 중인 포인터 캡처 대상 재정의가 더 이상 연결된 상태가 아니면 [DOM], 대기 중인 포인터 캡처 대상 재정의 노드를 지우는 것이 좋다.
lostpointercapture 이벤트가 문서에서
발생한다.
요소에 포인터 잠금 [PointerLock]이 성공적으로 적용되었을 때, 캡처되도록 설정되었거나
캡처 대기 중인 요소가 하나라도 있다면 사용자
에이전트는 releasePointerCapture 메서드가
호출된 것처럼 단계를 실행해야 한다.
성능상의 이유로 사용자 에이전트는 포인터의 측정 가능한 속성
(예: 좌표, 압력, 접선 압력, 기울기, 비틀림 또는 접촉 형상)이 갱신될 때마다 pointermove 이벤트를 전송하지 않도록 선택할 수 있다.
대신 여러 변경을 하나의 pointermove 또는 pointerrawupdate 이벤트로 병합
(결합/합치기)할 수 있다. 이 접근 방식은 사용자
에이전트가 수행해야 하는 이벤트 처리량을
줄이는 데 도움이 되지만, 특히 빠르고 큰 움직임의 경우 포인터 위치를 추적할 때 세분성과 정확도가 자연스럽게
감소한다. getCoalescedEvents 메서드를
사용하면 애플리케이션이 원시의 병합되지 않은 위치 변경에 접근할 수 있다. 이를 통해 포인터 이동 데이터를
더 정밀하게 처리할 수 있다. 예를 들어 그리기 애플리케이션에서는 병합되지 않은 이벤트를 사용하여
포인터의 실제 움직임에 더 가깝게 일치하는 부드러운 곡선을 그릴 수 있다.
pointermove 이벤트의
병합된 좌표(회색 점)만 사용하면 곡선이 눈에 띄게 각지고 들쭉날쭉하지만,
getCoalescedEvents()가 제공하는 더 세분화된 점(빨간색 원)을 사용하여
동일한 선을 그리면 포인터 움직임을 더 부드럽게 근사할 수 있다.PointerEvent에는 연결된 병합된
이벤트 목록(0개 이상의
PointerEvent 목록)이 있다. 신뢰할 수 있는 pointermove 및
pointerrawupdate 이벤트의 경우 이 목록은
해당 이벤트로 병합된 모든 PointerEvent의 시퀀스이다. "부모"인 신뢰할 수 있는
pointermove 및
pointerrawupdate 이벤트는 이러한 병합된
이벤트의 누적을 나타내지만 추가 처리가 적용될 수 있다(예: 디스플레이 재생률에 맞추기 위해).
따라서 이러한 이벤트의 병합된 이벤트 목록에는 항상 최소 하나의 이벤트가 포함된다.
그 밖의 모든 신뢰할 수 있는 이벤트 유형에서는 빈 목록이다. 신뢰할 수 없는 이벤트의
병합된 이벤트 목록은 생성자에 전달된 값으로 초기화된다.
isTrusted 비트를
false로 설정하지만 병합된
이벤트 목록의 동일한 비트는 원래의 true 값에서 변경되지 않는다.
신뢰할 수 있는 이벤트의 병합된 이벤트 목록에 있는 이벤트는 다음을 가진다:
timeStamp 값
[DOM] — 모든
병합된 이벤트에는
timeStamp가 있으며,
이는 getPredictedEvents 메서드가
호출된 디스패치된 포인터 이벤트의 timeStamp보다 작거나
같다. 병합된 이벤트 목록은 timeStamp를 기준으로
시간순으로 정렬되어야 하므로 첫 번째 이벤트의 timeStamp가 가장 작다.
pointerId,
pointerType,
및 isPrimary.
<style>
/* 사용자 에이전트 고유의 직접 조작 동작(예: 패닝 또는 확대/축소)을 비활성화하여
캔버스 요소의 모든 이벤트가 대신 애플리케이션에 전달되도록 한다. */
canvas { touch-action: none; }
</style>
<canvas id="drawSurface" width="500px" height="500px" style="border:1px solid black;"></canvas>
<script>
const canvas = document.getElementById("drawSurface"),
context = canvas.getContext("2d");
canvas.addEventListener("pointermove", (e)=> {
if (e.getCoalescedEvents) {
for (let coalesced_event of e.getCoalescedEvents()) {
paint(coalesced_event); // 모든 원시/병합되지 않은 점을 그린다
}
} else {
paint(e); // 최종 병합된 점을 그린다
}
});
function paint(event) {
if (event.buttons>0) {
context.fillRect(event.clientX, event.clientY, 5, 5);
}
}
</script>
디스패치된 이 모든 이벤트의 순서는 원래 이벤트의 실제 순서와 일치해야 한다.
예를 들어 pointerdown 이벤트가 병합된
pointermove 이벤트의 디스패치를 발생시키는 경우
사용자 에이전트는 먼저 특정
pointerId의
모든 병합된 이벤트를 포함하는 하나의 pointermove 이벤트를 디스패치한 다음
pointerdown 이벤트를 디스패치해야
한다.
다음은 증가하는 timeStamp 값과 함께
실제로 발생한 이벤트와 사용자 에이전트가 디스패치한 이벤트의 예이다:
| 실제 이벤트 | 디스패치된 이벤트 |
|---|---|
포인터(pointerId=2)
좌표 변경 |
pointerrawupdate (pointerId=2),
병합된 이벤트 1개 포함 |
포인터(pointerId=1)
좌표 변경 |
pointerrawupdate (pointerId=1),
병합된 이벤트 1개 포함 |
포인터(pointerId=2)
좌표 변경 |
pointerrawupdate (pointerId=2),
병합된 이벤트 1개 포함 |
포인터(pointerId=2)
좌표 변경 |
pointerrawupdate (pointerId=2),
병합된 이벤트 1개 포함 |
포인터(pointerId=1)
좌표 변경 |
pointerrawupdate (pointerId=1),
병합된 이벤트 1개 포함 |
포인터(pointerId=2)
좌표 변경 |
pointerrawupdate (pointerId=2),
병합된 이벤트 1개 포함 |
포인터(pointerId=1) 버튼
누름 |
pointermove
(pointerId=1),
병합된 이벤트 2개 포함pointermove
(pointerId=2),
병합된 이벤트 4개 포함pointerdown
(pointerId=1),
병합된 이벤트 0개 포함 |
포인터(pointerId=2)
좌표 변경 |
pointerrawupdate (pointerId=2),
병합된 이벤트 1개 포함 |
포인터(pointerId=2)
좌표 변경 |
pointerrawupdate (pointerId=2),
병합된 이벤트 1개 포함 |
포인터(pointerId=1) 버튼
해제 |
pointermove
(pointerId=2),
병합된 이벤트 2개 포함pointerup (pointerId=1),
병합된 이벤트 0개 포함 |
일부 사용자 에이전트에는 일련의 확인된 포인터 이동 후 현재 제스처의 이전 이벤트와 이동 속도/궤적을
기반으로 미래 포인터 이동의 위치가 어디일지 예측할 수 있는 내장 알고리즘이 있다.
애플리케이션은 getPredictedEvents 메서드를
사용하여 이 정보를 활용하고, 인지되는 지연 시간을 줄이기 위해 예측된 위치까지 추측하여 "미리 그린" 다음
실제 점을 받으면 이러한 예측된 점을 버릴 수 있다.
pointermove 이벤트의 병합된 좌표를 사용하며,
사용자 에이전트가 예측한 미래 점(회색 원)을 보여 준다.PointerEvent에는 연결된 예측된
이벤트 목록(0개 이상의
PointerEvent 목록)이 있다. 신뢰할 수 있는 pointermove 이벤트의 경우 이 목록은 사용자 에이전트가
미래에 해당 이벤트 뒤에 이어질 것으로 예측하는 PointerEvent의 시퀀스이다.
그 밖의 모든 신뢰할 수 있는 이벤트 유형에서는 빈 목록이다.
신뢰할 수 없는 이벤트의 예측된 이벤트 목록은 생성자에 전달된
값으로 초기화된다.
pointerrawupdate 이벤트는 비어 있지 않은 병합된 이벤트
목록을 가질 수 있지만,
성능상의 이유로 예측된 이벤트 목록은 일반적으로 빈 목록이다.
isTrusted 비트를
false로 설정하지만 예측된
이벤트 목록의 동일한 비트는 원래의 true 값에서 변경되지 않는다.
목록의 이벤트 수와 현재 타임스탬프에서 얼마나 먼지는 사용자 에이전트 및 사용자 에이전트가 사용하는 예측 알고리즘에 의해 결정된다.
신뢰할 수 있는 이벤트의 예측된 이벤트 목록에 있는 이벤트는 다음을 가진다:
timeStamp 값
[DOM] — 모든
예측된 이벤트에는
timeStamp가 있으며,
이는 getPredictedEvents 메서드가
호출된 디스패치된 포인터 이벤트의 timeStamp보다 크거나
같다. 예측된 이벤트 목록은 timeStamp를 기준으로
시간순으로 정렬되어야 하므로 첫 번째 이벤트의 timeStamp가 가장 작다.
pointerId,
pointerType,
및 isPrimary.
저자는 다음 포인터 이벤트가 디스패치될 때까지만 예측된 이벤트를 유효한 예측으로 간주해야 한다. 사용자 에이전트가 얼마나 먼 미래의 이벤트를 예측하는지에 따라 일반 포인터 이벤트가 하나 이상의 예측된 이벤트의 타임스탬프보다 먼저 디스패치될 수 있다.
let predicted_points = [];
window.addEventListener("pointermove", function(event) {
// 이전에 그린 예측된 점을 지운다.
for (let e of predicted_points.reverse()) {
clearPoint(e.pageX, e.pageY);
}
// 마지막으로 수신한 이벤트 이후 실제로 발생한 움직임을 그린다.
for (let e of event.getCoalescedEvents()) {
drawPoint(e.pageX, e.pageY);
}
// 인지되는 지연 시간을 줄이기 위해 현재 예측된 점을 그린다.
predicted_points = event.getPredictedEvents();
for (let e of predicted_points) {
drawPoint(e.pageX, e.pageY);
}
});
신뢰할 수 있는 PointerEvent가 생성되면 사용자 에이전트는
병합된 이벤트 목록 및 예측된 이벤트 목록의 각
이벤트에 대해 다음 단계를
실행하는 것이 좋다:
pointerId,
pointerType,
isPrimary 및 isTrusted를
"부모" 포인터 이벤트의 각각 해당하는 속성과 일치하도록 설정한다.
cancelable 및 bubbles를 false로
설정한다(이 이벤트는 절대로 독립적으로 디스패치되지 않기 때문).PointerEvent 값으로 초기화한다.
신뢰할 수 있는 PointerEvent의 target이 변경되면 사용자 에이전트는
병합된 이벤트 목록 및 예측된 이벤트 목록의 각
이벤트에 대해 다음을
수행하는 것이 좋다:
오늘날 존재하는 웹 콘텐츠의 대다수는 Mouse Events만을 대상으로 코딩되어 있다. 다음에서는 이 콘텐츠와의 호환성을 위해 사용자 에이전트가 일반적인 포인터 입력을 마우스 이벤트에 매핑할 수 있는 알고리즘을 설명한다.
마우스 이벤트와의 호환성 매핑은 이 명세의 선택 사항인 기능이다. 사용자 에이전트는 기존 레거시 콘텐츠와 최상의 호환성을 제공하기 위해 이 기능을 지원하는 것이 권장된다.
개념적으로 호환성 마우스 이벤트는 각각에 해당하는 포인터 이벤트와 "교차 배치"되도록 의도되어 있다. 그러나 이 특정 순서는 필수가 아니며, 호환성 마우스 이벤트를 구현하는 사용자 에이전트는 상대적인 순서가 일관되기만 한다면 마우스 이벤트의 디스패치를 지연하거나 그룹화하기로 결정할 수 있다.
특히 터치스크린 입력의 경우 사용자 에이전트는 제스처 인식을 위한 추가적인 휴리스틱을 적용할
수 있다(저자가 을
통해 명시적으로 억제하지
않은 경우). touch-actionpointerdown 이벤트와 pointerup 이벤트 사이의 이벤트 시퀀스 동안,
제스처 인식은 제스처를 감지하거나 무시하기 위해 pointerup 이벤트까지 기다려야 할 수 있다.
그 결과 사용자 에이전트가 해당 상호작용이 특정 제스처를 의도한 것이 아니라고 판단한 경우,
전체 시퀀스의 호환성 마우스 이벤트가 마지막 pointerup 이벤트 이후 한꺼번에 디스패치될 수
있다.
사용자 에이전트의 이러한 제스처 인식 세부 사항은 이 명세에서 정의하지 않으며
구현마다 다를 수 있다.
호환성 마우스 이벤트 지원 여부와 관계없이 사용자 에이전트는 click,
auxclick 및 contextmenu 이벤트를 항상 지원해야 한다.
이러한 이벤트는 PointerEvent 유형이므로 호환성 마우스 이벤트가 아니기 때문이다. 포인터 이벤트
중에
preventDefault를 호출하는 것은 click, auxclick 또는
contextmenu가 발생하는지 여부에 영향을 주어서는 안 된다.
이러한 상위 수준 이벤트 중 일부(예: contextmenu, focus, blur)와 포인터 이벤트 간의
상대적 순서는 정의되어 있지 않으며 사용자 에이전트마다 다르다. 예를 들어 일부 사용자 에이전트에서는
contextmenu가 흔히 pointerup 뒤에 오지만, 다른 사용자
에이전트에서는 흔히
pointerup 또는 pointercancel보다 먼저 오며, 일부 상황에서는
해당하는 포인터 이벤트 없이도 발생할 수 있다(예: 키보드 상호작용의 결과).
또한 사용자 에이전트는 click, auxclick 또는
contextmenu 이벤트를 발생시켜야 하는지 여부를 판단하기 위해 자체 휴리스틱을 적용할 수 있다.
일부 사용자 에이전트는 동일한 유형의 다른 (주가 아닌) 포인터나 다른 유형의 다른 주 포인터가 있는 경우
이러한 이벤트를 발생시키지 않을 수 있다. 사용자 에이전트는 특정 동작이 "정상적인" 탭, 클릭 또는
길게 누르기가 아니었다고 판단하고(예: 터치스크린에서 손가락으로 상호작용할 때 손가락이 화면에 닿아 있는
동안 너무 많이 움직인 경우) click, auxclick 또는
contextmenu 이벤트를 발생시키지 않기로 결정할 수 있다. 사용자 에이전트 동작의 이러한
측면은 이 명세에서 정의하지 않으며 구현마다 다를 수 있다.
달리 언급되지 않는 한, 매핑된 모든 마우스 이벤트의 대상은 해당 대상이 더 이상
ownerDocument의 트리에 참여하지 않는 경우를 제외하면 각각의 포인터 이벤트와 동일한 대상인 것이
좋다. 이 경우 마우스 이벤트는 원래 대상이 트리에서 제거된 시점에
ownerDocument의 트리에 여전히 참여하고 있던 원래 대상의 가장 가까운 조상 노드에서 발생시키는 것이 좋다.
즉, 마우스 이벤트를 위해 (새 대상 노드를 기반으로 한) 새 이벤트 경로가 구성된다.
저자는 pointerdown 이벤트를 취소하여 특정 호환성 마우스 이벤트의
생성을 방지할 수 있다.
마우스 이벤트는 포인터가 눌린 상태일 때만 방지할 수 있다. 호버 중인 포인터(예: 아무 버튼도 눌리지 않은 마우스)의 마우스 이벤트는 방지할 수 없다.
mouseover, mouseout, mouseenter 및 mouseleave
이벤트는 절대로 방지되지 않는다(포인터가 눌린 상태인 경우에도).
포인터 이벤트 EventListener가
passive로
설정되어 있으면 [DOM] 호환성
마우스 이벤트를 방지할 수 없다.
주 포인터만 호환성 마우스 이벤트를 생성할 수 있지만,
여러 주 포인터가 동시에 활성 상태일 수 있으며, 각각 자체적인
호환성 마우스 이벤트를 생성할 수 있다. MouseEvents에 의존하는 스크립트와의 호환성을 위해 마우스 전환 이벤트
(mouseover, mouseout, mouseenter 및
mouseleave)는 단일 레거시 마우스 입력의 움직임을 시뮬레이션하는 것이
좋다. 이는 모든 이벤트 대상의 진입/이탈 상태가 유효하다는 의미이다.
사용자 에이전트는 다음과 같이 문서에서 레거시 마우스 포인터의 유효 위치를 유지하여 이를 보장하는 것이
좋다.
pointerdown, pointerup 또는 pointermove 이벤트를 발생시키기 직전, 또는
window에서 pointerleave 이벤트를 발생시키기 직전에
사용자 에이전트는 다음 단계를 실행하는 것이 좋다:
pointerdown, pointerup 또는 pointermove 이벤트의 대상으로 둔다. pointerleave 이벤트의 경우 T를 설정 해제한다.
mouseover,
mouseout, mouseenter 및 mouseleave 이벤트를 디스패치한다.
현재 레거시 마우스 포인터의 유효 위치 또는
T 중 하나가 설정 해제된 값이면 창 밖의 마우스 위치로 간주한다.
레거시
마우스 포인터의 유효 위치는 포인터 전환 이벤트(pointerover,
pointerout, pointerenter
및 pointerleave)를 해당 레거시 마우스 전환 이벤트
(mouseover,
mouseout, mouseenter 및 mouseleave)에 항상 직접
매핑할 수는 없다는 사실을 모델링한다. 다음 애니메이션은 두 개의 주 포인터를 하나의
레거시 마우스 입력으로 조정하기 위해 사용자 에이전트가 포인터 전환 이벤트보다 더 많은
레거시 마우스 전환 이벤트를 디스패치해야 하는 경우를 보여 준다.
이 애니메이션에서 마우스 클릭과 터치 탭 사이의 시간 구간에 유의한다. 버튼 1은
pointerout 이벤트를 받지 않는다("실제" 마우스 포인터가 이 구간 동안 버튼
사각형을 벗어나지 않았기 때문). 하지만 터치 탭으로 레거시 마우스 포인터의
유효 위치가 버튼 2로 이동할 때 버튼 1은 mouseout 이벤트를 받는다.
마찬가지로 터치 탭과 마우스가 버튼 1을 떠나기 직전 사이의 시간 구간 동안 버튼 1은 같은 이유로
pointerover 이벤트를 받지 않지만, 레거시 마우스 포인터의
유효 위치가 버튼 1 내부로 다시 이동하면 버튼 1은 mouseover 이벤트를 받는다.
사용자 에이전트가 호버를 지원하는 장치에 대해 포인터 이벤트를 디스패치할 때마다 다음 단계를 실행하는 것이 좋다:
isPrimary 속성이 false이면
포인터 이벤트를 디스패치하고 이 단계를 종료한다.pointerdown, pointerup 또는 pointermove 이벤트이거나,
window에서의 pointerleave 이벤트인 경우 레거시 마우스
포인터의 유효 위치 추적에 설명된 대로 호환성 마우스 전환 이벤트를 디스패치한다.
pointerdown이고 이벤트의 취소 플래그가 설정되어 있으면
이 pointerType에 대해 PREVENT MOUSE EVENT 플래그를 설정한다.
pointerType에 대해 PREVENT MOUSE EVENT 플래그가
설정되지 않았고 디스패치된 포인터 이벤트가 다음 중 하나이면:
pointerdown인 경우
mousedown 이벤트를 발생시킨다.
pointermove인 경우
mousemove 이벤트를 발생시킨다.
pointerup인 경우
mouseup 이벤트를 발생시킨다.
pointercancel인 경우
window에서 mouseup 이벤트를 발생시킨다.
pointerup 또는 pointercancel인 경우 이
pointerType에 대한 PREVENT MOUSE EVENT 플래그를 지운다.
대부분의 터치스크린과 같은 일부 장치는 활성 상태가 아닐 때 좌표(또는 좌표 집합)에 호버하는 것을 지원하지 않는다. 마우스 이벤트를 대상으로 작성된 기존 콘텐츠의 상당수는 마우스가 이벤트를 생성한다고 가정하므로 일반적으로 다음과 같은 특성이 참이라고 가정한다:
mousemove 이벤트를 생성할 가능성이 높다.
따라서 사용자 에이전트는 이러한 유형의 입력 장치에 대해 다른 매핑을 제공해야 한다. 사용자 에이전트가 호버를 지원하지 않는 장치에 대해 포인터 이벤트를 디스패치할 때마다 다음 단계를 실행하는 것이 좋다:
isPrimary 속성이 false이면
포인터 이벤트를 디스패치하고 이 단계를 종료한다.pointerover이고 이 포인터에 대한 pointerdown 이벤트가 아직 디스패치되지 않았다면
mousemove 이벤트를 발생시킨다(레거시 마우스 전용 코드와의 호환성을 위해).
pointerdown, pointerup 또는 pointermove 이벤트이거나,
window에서의 pointerleave 이벤트인 경우 레거시 마우스
포인터의 유효 위치 추적에 설명된 대로 호환성 마우스 전환 이벤트를 디스패치한다.
pointerdown이고 이벤트의 취소 플래그가 설정되어 있으면
이 pointerType에 대해 PREVENT MOUSE EVENT 플래그를 설정한다.
pointerType에 대해 PREVENT MOUSE EVENT 플래그가
설정되지 않았고 디스패치된 포인터 이벤트가 다음 중 하나이면:
pointerdown인 경우
mousedown 이벤트를 발생시킨다.
pointermove인 경우
mousemove 이벤트를 발생시킨다.
pointerup인 경우
mouseup 이벤트를 발생시킨다.
pointercancel인 경우
window에서 mouseup 이벤트를 발생시킨다.
pointerup 또는 pointercancel인 경우
이 pointerType에 대한 PREVENT MOUSE EVENT 플래그를 지운다.
사용자 에이전트가 Touch Events([TOUCH-EVENTS]에서 정의됨)와 Pointer Events를 모두 지원하는 경우 사용자 에이전트는 이 섹션에서 설명한 호환성 마우스 이벤트와 [TOUCH-EVENTS]에 설명된 대체 마우스 이벤트를 둘 다 생성해서는 안 된다.
호버를 지원하지 않는 주 포인터
(예: 터치스크린의 한 손가락)를 사용하여 요소를 활성화(click)하면 일반적으로
다음 이벤트 시퀀스가 생성된다:
mousemovepointeroverpointerentermouseovermouseenterpointerdownmousedownpointermove 및
mousemove 이벤트
pointerupmouseuppointeroutpointerleavemouseoutmouseleaveclick그러나 이 상호작용 중에 pointerdown 이벤트의
취소 플래그가
설정되면 이벤트 시퀀스는 다음과 같다:
mousemovepointeroverpointerentermouseovermouseenterpointerdownpointermove 이벤트
pointeruppointeroutpointerleavemouseoutmouseleaveclick마우스 이벤트 모듈은 [HTML401]의 onclick,
ondblclick, onmousedown, onmouseup, onmouseover,
onmousemove 및 onmouseout 속성에서 유래했다. 이 이벤트 모듈은 마우스나
트랙볼과 같은 포인팅 입력 장치와 함께 사용하도록 특별히 설계되었다.
DOM 레벨 2에서 도입되었으며 이 명세에서 수정되었다.
MouseEvent 인터페이스는 마우스 이벤트와 관련된
특정 컨텍스트 정보를 제공한다.
중첩된 요소의 경우 마우스 이벤트는 항상 가장 깊게 중첩된 요소를 대상으로 한다.
대상 요소의 조상은 이벤트 버블링을 사용하여 자손 요소 내부에서 발생하는 마우스 이벤트의 알림을 받을 수 있다.
MouseEvent 인터페이스의 인스턴스를
생성하려면 MouseEvent 생성자를 사용하고 선택적인 MouseEventInit 딕셔너리를 전달한다.
initMouseEvent를 사용하여 MouseEvent 객체를 초기화할 때
구현은 다른 좌표(DOM 레벨 0 구현이 노출하는 대상 좌표 또는 기타 독점 속성, 예:
pageX)를 계산하기 위해 클라이언트 좌표 clientX 및 clientY를 사용할 수 있다.
WebIDLdictionary MouseEventInit : EventModifierInit {
long screenX = 0;
long screenY = 0;
long clientX = 0;
long clientY = 0;
short button = 0;
unsigned short buttons = 0;
};
[Exposed=Window]
interface MouseEvent : UIEvent {
constructor(DOMString type, optional MouseEventInit eventInitDict = {});
readonly attribute long screenX;
readonly attribute long screenY;
readonly attribute long clientX;
readonly attribute long clientY;
readonly attribute long layerX;
readonly attribute long layerY;
readonly attribute boolean ctrlKey;
readonly attribute boolean shiftKey;
readonly attribute boolean altKey;
readonly attribute boolean metaKey;
readonly attribute short button;
readonly attribute unsigned short buttons;
boolean getModifierState(DOMString keyArg);
};
screenX화면 좌표계의 원점을 기준으로 이벤트가 발생한 수평 좌표.
이 속성의 초기화되지
않은 값은
0이어야 한다.
screenY화면 좌표계의 원점을 기준으로 이벤트가 발생한 수직 좌표.
이 속성의 초기화되지
않은 값은
0이어야 한다.
clientX이벤트와 연결된 뷰포트를 기준으로 이벤트가 발생한 수평 좌표.
이 속성의 초기화되지
않은 값은
0이어야 한다.
clientY이벤트와 연결된 뷰포트를 기준으로 이벤트가 발생한 수직 좌표.
이 속성의 초기화되지
않은 값은
0이어야 한다.
layerX
조상 요소 중 스태킹 컨텍스트이거나, 위치가 지정되어 있거나, 스태킹 컨텍스트를 페인트할 때 위치 지정 단계에서 페인트되는 가장 가까운 요소로부터의 수평 오프셋.
이 속성의 초기화되지
않은 값은
0이어야 한다.
layerY
조상 요소 중 스태킹 컨텍스트이거나, 위치가 지정되어 있거나, 스태킹 컨텍스트를 페인트할 때 위치 지정 단계에서 페인트되는 가장 가까운 요소로부터의 수직 오프셋.
이 속성의 초기화되지
않은 값은
0이어야 한다.
ctrlKeyKeyboardEvent의 ctrlKey
속성을 참조한다.
이 속성의 초기화되지
않은 값은
false이어야 한다.
shiftKeyKeyboardEvent의 shiftKey
속성을 참조한다.
이 속성의 초기화되지
않은 값은
false이어야 한다.
altKey
KeyboardEvent의 altKey
속성을 참조한다.
이 속성의 초기화되지
않은 값은
false이어야 한다.
metaKeyKeyboardEvent의 metaKey
속성을 참조한다.
이 속성의 초기화되지
않은 값은
false이어야 한다.
button
마우스 버튼을 누르거나 놓음으로 인해 발생하는 마우스 이벤트 동안 button은 어떤 포인터 장치
버튼의
상태가 변경되었는지 나타내는 데 사용해야 한다.
button 속성의 값은 다음과
같아야 한다:
0은 장치의 주 버튼(일반적으로 왼쪽 버튼 또는 단일 버튼 장치의 유일한 버튼으로,
사용자 인터페이스 컨트롤을 활성화하거나 텍스트를 선택하는 데 사용됨) 또는 초기화되지 않은 값을
나타내야 한다.1은 보조 버튼(일반적으로 가운데 버튼으로, 흔히 마우스 휠과 결합됨)을
나타내야 한다.2는 보조 주 버튼(일반적으로 오른쪽 버튼으로, 흔히 컨텍스트 메뉴를 표시하는 데 사용됨)을
나타내야 한다.3은 X1(뒤로) 버튼을 나타내야 한다.4는 X2(앞으로) 버튼을 나타내야 한다.일부 포인팅 장치는 더 많은 버튼 상태를 제공하거나 시뮬레이션하며, 이러한 버튼을 나타내기 위해
2보다 크거나 0보다 작은 값을 사용할 수 있다.
마우스 버튼을 누르거나 놓음으로 인해 발생하지 않은 이벤트에서는 button 값이
갱신되지 않는다. 이러한 상황에서는 값 0을 왼쪽 버튼으로 해석하지 말고
기본값으로 해석하도록 주의한다.
이 속성의 초기화되지
않은 값은
0이어야 한다.
buttons모든 마우스 이벤트 동안 buttons는
현재 어떤 마우스 버튼 조합이 눌려 있는지를 비트마스크로 나타내는 데 사용해야 한다.
buttons 속성은 비트 필드이다.
비트 필드 값에 마스크 값 1을 적용했을 때 참이면 주 마우스 버튼이 눌린 상태이다.
비트 필드 값에 마스크 값 2를 적용했을 때 참이면 오른쪽 마우스 버튼이 눌린 상태이다.
비트 필드 값에 마스크 값 4를 적용했을 때 참이면 보조/가운데 버튼이 눌린 상태이다.
이름은 비슷하지만 buttons 속성과 button 속성의 값은 매우 다르다.
button 값은
mousedown / mouseup 이벤트 핸들러 동안 유효하다고
가정하는 반면, buttons 속성은
"현재 활성화된 버튼 없음" 상태(0)를 나타낼 수 있으므로 신뢰할 수 있는 모든 MouseEvent 객체가 디스패치되는 동안
마우스 버튼의 상태를 반영한다.
buttons 속성의 값은 다음과
같아야 한다:
0은 현재 활성화된 버튼이 없음을 나타내야 한다.1은 장치의 주 버튼(일반적으로 왼쪽 버튼 또는 단일 버튼 장치의 유일한 버튼으로,
사용자 인터페이스 컨트롤을 활성화하거나 텍스트를 선택하는 데 사용됨)을 나타내야 한다.2는 보조 주 버튼(일반적으로 오른쪽 버튼으로, 존재하는 경우 흔히 컨텍스트 메뉴를
표시하는 데 사용됨)을 나타내야 한다.4는 보조 버튼(일반적으로 가운데 버튼으로, 흔히 마우스 휠과 결합됨)을
나타내야 한다.일부 포인팅 장치는 더 많은 버튼을 제공하거나 시뮬레이션한다. 이러한 버튼을 나타내려면 이후의
각 버튼마다 값이 두 배가 되어야 한다(이진수 계열
8, 16, 32, ... ).
임의의 버튼 값 집합의 합은 고유한 숫자이므로 콘텐츠 저자는 비트 연산을 사용하여
장치의 임의 개수의 마우스 버튼에 대해 현재 몇 개의 버튼이 눌려 있고 어떤 버튼인지 확인할 수 있다.
예를 들어 값 3은 왼쪽 버튼과 오른쪽 버튼이 현재 모두 눌려 있음을 나타내며,
값 5는 왼쪽 버튼과 가운데 버튼이 현재 모두 눌려 있음을 나타낸다.
이 속성의 초기화되지
않은 값은
0이어야 한다.
relatedTarget이벤트 유형에 따라 UI 이벤트와 관련된 보조 EventTarget을 식별하는 데 사용한다.
이 속성의 초기화되지
않은 값은
null이어야 한다.
relatedTarget은 마우스 포인터가
방금 경계를 벗어난 요소(mouseover 또는 mouseenter 이벤트의 경우) 또는 마우스 포인터가
경계 안으로 들어가는 요소(mouseout, mouseleave 또는 focusout 이벤트의 경우)로 초기화하는 것이 좋다.
다른 이벤트에서는 이 값을 할당할 필요가 없으며 기본값은 null이다.
getModifierState(keyArg)키 값을 사용하여 수정자 상태를 조회한다.
수정자 키이고 수정자가 활성화되어 있으면 true를 반환하고,
그렇지 않으면 false를 반환한다.
DOMString keyArg
KeyboardEvent의 getModifierState()
메서드를 참조한다.구현은 마우스 이벤트를 생성할 때 현재 클릭 횟수를 유지해야 한다. 이는 특정 시간 내에 포인팅 장치 버튼이 연속으로 클릭된 횟수를 나타내는 음이 아닌 정수여야 한다. 횟수가 재설정되는 지연 시간은 환경 구성에 따라 다르다.
이 섹션의 알고리즘은 네이티브 플랫폼 OS가 다음을 제공한다고 가정한다:
이러한 이벤트에 대해 OS는 다음 정보를 제공할 수 있다:
이 섹션은 수정이 필요하다.
일반적으로 Event 인터페이스 또는 Event 인터페이스에서 상속된 인터페이스의
생성자가 호출되면 [DOM]에 설명된 단계를 따라야 한다. 그러나 MouseEvent 인터페이스는 Event 객체의 키
수정자 내부 상태를 초기화하기 위한 추가 딕셔너리 멤버를 제공한다. 구체적으로는 getModifierState()
메서드로 조회하는 내부 상태이다. 이 섹션은 이러한 선택적 수정자 상태를 사용하여 새로운 MouseEvent 객체를 초기화하기 위한
[DOM] 단계를
보완한다.
아래 알고리즘을 사용하여 MouseEvent 또는 이러한 객체에서 파생된 객체를
구성하기 위해 모든 MouseEvent 및 파생 객체는
[UIEvents-Key]의 수정자 키 표에 설명된 키 수정자 이름을 사용하여 설정하고
가져올 수 있는 내부 키 수정자 상태를 가진다.
다음 단계는 [DOM]에 정의된 이벤트 구성 알고리즘을 보완한다:
Event가 MouseEvent 객체 또는 그로부터 파생된 객체이고,
EventModifierInit
인수가 생성자에 제공된 경우 다음 하위 단계를 실행한다:
EventModifierInit
인수에 대해 딕셔너리 멤버가 문자열 "modifier"로 시작하면 키
수정자 이름을 접두사
"modifier"를 제외한 딕셔너리 멤버의 이름으로 두고, 해당 키 수정자 이름과 일치하는 Event 객체의 내부 키
수정자 상태를 해당 값으로 설정한다.
이 섹션은 수정이 필요하다.
UA는 전체 사용자 에이전트에서 공유되는 다음 값을 유지해야 한다.
마우스 버튼의 현재 상태를 추적하는 마우스 버튼 비트마스크.
UA는 Window에서 공유되는 다음 값을 유지해야 한다.
MouseEvent를 전송한 마지막 Element를 추적하는 마지막
마우스 요소 값(초기에는 undefined).
가장 최근의 마우스 이벤트가 전송되었을 때 마지막 마우스 요소의 조상 Element들의 스냅샷을 포함하는
마지막
마우스 DOM 경로 값(초기에는 비어 있음).
이 섹션은 수정이 필요하다.
MouseEvent에는 다양한 수정자 키의 상태를 추적하는 데
사용되는 다음 내부 플래그가 있다:
shift 플래그,
control
플래그,
alt 플래그,
altgraph
플래그,
그리고 meta 플래그.
해당 수정자 키가 마우스 이벤트 시점에 눌려 있었다면 이러한 플래그가 설정된다.
이 섹션은 수정이 필요하다.
elementFromPoint()
(pos에서 가장 앞쪽에 있는 DOM 요소)를 반환한다
비활성 또는 사용 불가
요소를 고려하려면, 이는 elementsFromPoint()를
호출하고 유효하지 않은 요소를 제외해야 한다.
MouseEvent 초기화이 섹션은 수정이 필요하다.
event, eventType 및 eventTarget, bubbles, 그리고 cancelable로 MouseEvent를 초기화하려면 다음 단계를 실행한다:
screenX를 데스크톱의 원점을 기준으로
이벤트가 발생한 위치의 x 좌표로 설정한다
screenY를 데스크톱의 원점을 기준으로
이벤트가 발생한 위치의 y 좌표로 설정한다
clientX를 뷰포트의 원점을 기준으로 이벤트가
발생한 위치의 x 좌표로 설정한다
clientY를 뷰포트의 원점을 기준으로 이벤트가
발생한 위치의 y 좌표로 설정한다
button을 0으로 설정한다
buttons를 마우스 버튼 비트마스크로 설정한다
여기에서 PointerLock을 하드코딩하는 대신 이를 위한 훅을 제공해야 한다.
이 섹션은 수정이 필요하다.
MouseEvent로 둔다
shiftKey를 true로 설정하고,
그렇지 않으면 false로 설정한다
ctrlKey를 true로 설정하고,
그렇지 않으면 false로 설정한다
altKey를 true로 설정하고,
그렇지 않으면 false로 설정한다
metaKey를 true로 설정하고,
그렇지 않으면 false로 설정한다
이 섹션은 수정이 필요하다.
MouseEvent 유형을 포함하는
DOMString으로 둔다EventTarget으로 둔다
MouseEvent를 사용하여 이벤트를 생성한
결과로 둔다이 섹션은 수정이 필요하다.
MouseEvent 유형을 포함하는
DOMString으로 둔다EventTarget으로 둔다
MouseEvent를 사용하여 이벤트를 생성한
결과로 둔다이 섹션은 수정이 필요하다.
MouseEvent로 둔다
TODO.
type이 [
mousedown, mouseup ] 중 하나이면
button을
mbutton으로 MouseEvent button 속성
계산한 결과로 설정한다
이 섹션은 수정이 필요하다.
다른 버튼은 0x08부터 추가할 수 있다.
이 섹션은 수정이 필요하다.
mousedown과 mouseup 사이에 다른 마우스 이벤트가 발생할 수 있다.
이 섹션은 수정이 필요하다.
플랫폼은 클릭을 생성하는 mouseup에 대해 네이티브 마우스 업 처리 직후에 이를 호출해야 한다.
이 섹션은 수정이 필요하다.
EventTarget으로 둔다
screenX가
정숫값이 아니면 반올림한다.screenY가
정숫값이 아니면 반올림한다.PointerEvents 및 반올림된 좌표를 사용하는 브라우저에 관한 정보는 pointerevents/100을 참조한다.
모든 "기본 동작"은 디스패치 중에 대상의 활성화 동작 알고리즘을 트리거하여 처리된다. 따라서 여기에서 이를 처리할 필요는 없다. 그러나 기존 명세가 disabled/css-pointer-events/inert/...를 처리하는지 확인해야 한다.
HTMLelement.click()을 처리하려면 native =
null 및 target = HTMLelement로 이 알고리즘을 호출한다.
키보드에서 시작된 클릭을 처리하려면 native = null 및 target = 현재 포커스된 요소로 이 알고리즘을 호출한다.
이 섹션은 수정이 필요하다.
더블 클릭을 생성하는 마우스 클릭의 경우 네이티브 마우스 클릭 처리 직후에 이를 호출해야 한다.
screenX가 정숫값이 아니면
반올림한다.screenY가 정숫값이 아니면
반올림한다.이 섹션은 수정이 필요하다.
이 알고리즘은 PointerEvents의 디스패치가 현재 명시적으로 규정되어 있지 않기 때문에 이에 대해 몇 가지 가정을 한다. pointerevents/285가 해결되면 이를 갱신해야 할 수 있다.
TODO: native에서 mouseout 속성을 설정한다. +CSSOM 속성.
취소된 경우의 동작을 확인해야 한다(영향이 없는 것으로 보임).
element가 삭제된 경우를 처리한다. 또한 이동된 경우도 처리한다: DOM 변형이 mouseleave 이벤트를 트리거했어야 하는가? 지금 전송해야 하는가? 폐기해야 하는가? 현재 브라우저가 무엇을 하는지 확인해야 한다.
Event.composed
= false로 설정한다
호환성 확인: event.composed의 값. 명세에서는 false라고 한다. Chrome/Linux = true. Firefox/Linux = false.
TODO: native에서 mouseout 속성을 설정한다. +CSSOM 속성.
취소된 경우의 동작을 확인해야 한다(영향이 없는 것으로 보임).
element가 삭제되거나 이동된 경우를 처리한다.
Event.composed
= false로 설정한다
호환성 확인: event.composed의 값. 명세에서는 false라고 한다. Chrome/Linux = true. Firefox/Linux = false.
shadow DOM 요소의 호환성을 확인해야 한다. Chrome/Linux는 요소와 shadow root에서 이 이벤트를 발생시킨다.
이 명세에서 정의된 특정 마우스 이벤트는 서로에 대해 정해진 순서로 발생해야 한다. 다음은 포인팅 장치의 커서가 요소 위로 이동할 때 발생해야 하는 이벤트 시퀀스를 보여 준다:
| # | 이벤트 유형 | 요소 | 참고 |
|---|---|---|---|
| 1 | mousemove |
||
| 포인팅 장치가 요소 A 안으로 이동한다... | |||
| 2 | mouseover |
A | |
| 3 | mouseenter |
A | |
| 4 | mousemove |
A | 여러 mousemove 이벤트 |
| 포인팅 장치가 요소 A 밖으로 이동한다... | |||
| 5 | mouseout |
A | |
| 6 | mouseleave |
A |
포인팅 장치가 요소 A 안으로 이동한 다음 중첩된 요소 B 안으로 이동하고 다시 밖으로 이동할 때 다음 이벤트 시퀀스가 발생해야 한다:
| 이벤트 유형 | 요소 | 참고 | |
|---|---|---|---|
| 1 | mousemove |
||
| 포인팅 장치가 요소 A 안으로 이동한다... | |||
| 2 | mouseover |
A | |
| 3 | mouseenter |
A | |
| 4 | mousemove |
A | 여러 mousemove 이벤트 |
| 포인팅 장치가 중첩된 요소 B 안으로 이동한다... | |||
| 5 | mouseout |
A | |
| 6 | mouseover |
B | |
| 7 | mouseenter |
B | |
| 8 | mousemove |
B | 여러 mousemove 이벤트 |
| 포인팅 장치가 요소 B에서 A로 이동한다... | |||
| 9 | mouseout |
B | |
| 10 | mouseleave |
B | |
| 11 | mouseover |
A | |
| 12 | mousemove |
A | 여러 mousemove 이벤트 |
| 포인팅 장치가 요소 A 밖으로 이동한다... | |||
| 13 | mouseout |
A | |
| 14 | mouseleave |
A |
경우에 따라 CSS를 사용하여 요소를 시각적으로 겹칠 수 있다. 다음 예에서 A, B, C로 표시된 세 요소는 모두 웹 페이지에서 동일한 크기와 절대 위치를 가진다. DOM에서 요소 C는 B의 자식이고, B는 A의 자식이다:
포인팅 장치가 요소 스택 바깥에서 C로 표시된 요소로 이동한 다음 다시 밖으로 이동하면 다음 일련의 이벤트가 발생해야 한다:
| 이벤트 유형 | 요소 | 참고 | |
|---|---|---|---|
| 1 | mousemove
|
||
| 포인팅 장치가 스택의 최상위 요소인 요소 C 안으로 이동한다 | |||
| 2 | mouseover
|
C | |
| 3 | mouseenter
|
A | |
| 4 | mouseenter
|
B | |
| 5 | mouseenter
|
C | |
| 6 | mousemove
|
C | 여러 mousemove 이벤트
|
| 포인팅 장치가 요소 C 밖으로 이동한다... | |||
| 7 | mouseout
|
C | |
| 8 | mouseleave
|
C | |
| 9 | mouseleave
|
B | |
| 10 | mouseleave
|
A |
mouseover/mouseout 이벤트는 한 번만 발생하지만, mouseenter/mouseleave 이벤트는 세 번(각 요소마다 한 번씩)
발생한다.
다음은 포인팅 장치와 연결된 버튼(예: 마우스 버튼 또는 트랙패드)을 요소 위에서 눌렀다가 놓을 때의 일반적인 이벤트 시퀀스이다:
| 이벤트 유형 | 참고 | |
|---|---|---|
| 1 | mousedown
|
|
| 2 | mousemove
|
선택 사항, 여러 이벤트, 일부 제한 |
| 3 | mouseup
|
|
| 4 | click
|
|
| 5 | mousemove
|
선택 사항, 여러 이벤트, 일부 제한 |
| 6 | mousedown
|
|
| 7 | mousemove
|
선택 사항, 여러 이벤트, 일부 제한 |
| 8 | mouseup
|
|
| 9 | click
|
|
| 10 | dblclick
|
click 또는 dblclick
이벤트가 계속 발생할 수 있는 범위에서
mousedown과 mouseup 이벤트 사이에 허용되는 지연 시간, 정도,
거리 및 mousemove 이벤트의 수는 구현, 장치 및 플랫폼에 따라
다르다. 이러한 허용 오차는 손 떨림과 같은 신체적 장애가 있는 사용자가 포인팅 장치와
상호작용할 때 도움을 줄 수 있다.
각 구현은 적절한 히스테리시스
허용 오차를 결정하지만, 일반적으로 연관된 mousedown
및
mouseup 이벤트의 이벤트 대상이 동일한 요소이고 그 사이에
mouseout 또는
mouseleave 이벤트가 없는 경우 click 및 dblclick
이벤트를 발생시키는 것이 좋고, 연관된 mousedown 및
mouseup 이벤트의 대상이 서로 다른 경우에는
가장 가까운 공통 포괄 조상에서 click 및
dblclick 이벤트를 발생시키는 것이
좋다.
mousedown 이벤트의 대상이 HTML 문서의 body
요소이고, 이에 해당하는 mouseup 이벤트의 대상이
문서 요소인 경우
click 이벤트는 가장 가까운 공통 포괄 조상이므로
문서
요소에 디스패치된다.
대상(예: 대상 요소)이 마우스 이벤트 시퀀스 중에 DOM에서 제거되면 시퀀스의 나머지 이벤트는 해당 요소에서 발생해서는 안 된다.
mousedown 이벤트의 결과로 대상 요소가 DOM에서 제거되면
해당 요소에 대해서는 mouseup, click 또는 dblclick 이벤트나 어떤 기본
활성화 이벤트도 디스패치되지 않는다. 그러나 mouseup 이벤트는 초기 대상 요소가
제거된 후 마우스에 노출된 요소에서 계속 디스패치된다. 마찬가지로 mouseup 이벤트의
디스패치 중에 대상 요소가 DOM에서 제거되면
click 및 후속 이벤트는 디스패치되지 않는다.
Mouse 이벤트 유형은 아래에 나열되어 있다. 중첩된 요소의 경우 마우스 이벤트 유형은 항상 가장 깊이 중첩된 요소를 대상으로 한다. 대상 요소의 조상은 버블링을 사용하여 자손 요소 내에서 발생하는 마우스 이벤트에 대한 알림을 받을 MAY.
| 유형 | auxclick
|
|---|---|
| 인터페이스 | PointerEvent
|
| 버블링 | 예 |
| 취소 가능 | 예 |
| 합성 | 예 |
| 컨텍스트 (신뢰할 수 있는 이벤트) |
사용자가 주가 아닌 포인터 버튼을 누르고 놓거나, 그와 같은 동작을 시뮬레이션하는 방식으로
포인터를 활성화하는 경우 auxclick 이벤트 유형은 포인터가 가리키는 최상위
이벤트 대상에 디스패치되어MUST 한다. 마우스 버튼의 작동
방식은 포인터 장치와 환경 구성에 따라 달라지며, 예를 들어 화면
위치나 포인팅 장치 버튼을 누르고 놓는 사이의 지연 시간에
따라 달라질 MAY 있다.
auxclick 이벤트는 주가 아닌 포인터
버튼에 대해서만 발생시키는 것이 좋다(즉, button 값이 0이 아니고,
buttons 값이
1보다 큰 경우). 주 버튼
(표준 마우스의 왼쪽 버튼 등)은
auxclick 이벤트를 발생시켜MUST NOT
한다. 주 버튼과
연결된 해당 이벤트는 click을 참조한다.
auxclick 이벤트보다 먼저 동일한 요소에서 mousedown 및
mouseup 이벤트가 발생할 MAY 있으며,
다른 노드 유형
(예: 텍스트 노드) 사이의 변화는 무시한다. 환경
구성에 따라 포인팅 장치 버튼을 누르고
놓는 사이에 mouseover,
mousemove 및 mouseout 이벤트 유형 중 하나 이상이 발생하더라도
auxclick 이벤트가 디스패치될 MAY
있다.
auxclick 이벤트 유형의 기본 동작은
이벤트의 대상과
button 또는 buttons 속성 값에 따라 달라진다.
auxclick 이벤트 유형의 일반적인
기본 동작은
다음과 같다:
myLink.addEventListener("auxclick", function(e) {
if (e.button === 1) {
// 예를 들어 링크를 가운데 클릭할 때 새 탭을 여는
// 기본 동작을 방지한다.
e.preventDefault();
// 앱에 맞는 방식으로 새 탭에서 링크 또는 링크가 아닌 버튼을
// 여는 것처럼 가운데 버튼 클릭을 처리하기 위한 다른 작업을 수행한다.
// 탭 표시줄에서 탭을 닫는 것처럼 클릭 동작에서 수행해야 하는
// 다른 작업도 여기에서 수행할 수 있다.
}
});
오른쪽 버튼의 경우 auxclick 이벤트는
모든 contextmenu 이벤트 뒤에 디스패치된다. 일부 사용자
에이전트는 컨텍스트 메뉴가 표시되는 동안 모든 입력
이벤트를 삼키므로 이러한 시나리오에서는 애플리케이션이 auxclick을
사용할 수 없을 수 있음에 유의한다.
자세한 설명은 예제 10을
참조한다.
myDiv.addEventListener("contextmenu", function(e) {
// 이 호출은 컨텍스트 메뉴가 표시되어
// 페이지의 이벤트 수신을 방해하지 않도록 한다.
e.preventDefault();
});
myDiv.addEventListener("auxclick", function(e) {
if (e.button === 2) {
// 앱 내부에서 사용자 정의 컨텍스트 메뉴를 여는 것처럼
// 오른쪽 버튼 클릭을 처리하기 위한 다른 작업을 수행한다.
}
});
| 유형 | click
|
|---|---|
| 인터페이스 | PointerEvent
|
| 버블링 | 예 |
| 취소 가능 | 예 |
| 합성 | 예 |
| 컨텍스트 (신뢰할 수 있는 이벤트) |
사용자가 주 포인터 버튼을 누르고 놓거나, 그와 같은 동작을 시뮬레이션하는 방식으로
포인터를 활성화하는 경우 click 이벤트 유형은 포인터가 가리키는 최상위
이벤트 대상에 디스패치되어MUST 한다. 마우스 버튼의 작동
방식은 포인터 장치와 환경 구성에 따라 달라지며, 예를 들어 화면
위치나 포인팅 장치 버튼을 누르고 놓는 사이의 지연 시간에
따라 달라질 MAY 있다.
click 이벤트는 주 포인터
버튼에 대해서만 발생시키는 것이 좋다(즉, button 값이 0이고,
buttons 값이 1인 경우).
보조 버튼
(표준 마우스의 가운데 또는 오른쪽 버튼 등)은
click 이벤트를 발생시켜MUST NOT 한다.
주가 아닌 버튼과
연결된 해당 이벤트는 auxclick을 참조한다.
click 이벤트보다 먼저 mousedown 및
mouseup 이벤트가 동일한 요소에서 발생할 MAY 있으며, 다른 노드 유형
(예: 텍스트 노드) 사이의 변화는 무시한다. 환경
구성에 따라 포인팅 장치 버튼을 누르고
놓는 사이에 mouseover,
mousemove 및 mouseout 이벤트 유형 중 하나 이상이 발생하더라도
click 이벤트가 디스패치될 MAY 있다. 또한
click 이벤트 뒤에
dblclick 이벤트가
이어질 MAY 있다.
사용자가 큰 line-height가 적용된
<p> 요소의 텍스트 노드 자식에서 마우스 버튼을 누른 뒤,
마우스를 약간 움직여 더 이상 텍스트가 포함된 영역 위에는 있지 않지만
여전히 해당 <p> 요소의 포함 블록 안에 있는 경우
(즉, 포인터가 동일한 텍스트 블록의 줄 사이에 있지만 텍스트 노드 자체
위에는 있지 않은 경우), 이후 마우스 버튼을 놓으면
사용자가 동일한 요소의 범위 내에 머물렀으므로 일반적인 시간적
히스테리시스 범위 내라면 click에 대해
여전히 click 이벤트가 발생할 가능성이 높다.
사용자 에이전트가 생성한
마우스 이벤트는 텍스트 노드에 디스패치되지 않는다는 점에 유의한다.
포인터 장치와 연결되는 것 외에도
click 이벤트 유형은 요소
활성화의 일부로 디스패치되어MUST 한다.
최대한의 접근성을 위해 콘텐츠 저자는 사용자 정의
컨트롤의 활성화 동작을 정의할 때 click 이벤트 유형을 사용하는 것이 권장되며,
mousedown 또는 mouseup처럼 장치에 더 종속적인 다른 포인팅 장치
이벤트 유형을 사용하는 것은 권장되지 않는다.
click 이벤트 유형은 포인터
장치(예: 마우스)에서 유래했지만 이후 구현 개선을 통해
이러한 연결을 넘어 확장되었으며, 요소 활성화를 위한
장치 독립적인 이벤트 유형으로 간주할 수 있다.
click 이벤트 유형의 기본 동작은
이벤트의 대상과
button 또는 buttons 속성 값에 따라 달라진다.
click 이벤트 유형의 일반적인
기본 동작은
다음과 같다:
| 유형 | dblclick |
|---|---|
| 인터페이스 | MouseEvent |
| 버블링 | 예 |
| 취소 가능 | 예 |
| 합성 | 예 |
| 컨텍스트 (신뢰할 수 있는 이벤트) |
사용자 에이전트는
포인팅 장치의 주 버튼이 요소 위에서 두 번 클릭될 때 이 이벤트를
디스패치해MUST 한다. 더블 클릭의
정의는 환경 구성에 따라 달라지지만, 이벤트 대상은
mousedown, mouseup 및 dblclick 사이에서 동일해MUST 한다.
클릭과 더블 클릭이 동시에 발생하는 경우
이 이벤트 유형은 click 이벤트 유형 뒤에 디스패치되어MUST
하며, 그렇지 않은 경우
mouseup 이벤트 유형 뒤에 디스패치되어야 한다.
click 이벤트와 마찬가지로 dblclick 이벤트는
주 포인터 버튼에 대해서만 발생시키는 것이 좋다. 보조 버튼은
dblclick 이벤트를 발생시켜MUST NOT
한다.
click 이벤트 유형과 마찬가지로 dblclick 이벤트 유형의 기본 동작은
이벤트의 대상과
button
또는 buttons 속성 값에 따라 달라진다.
dblclick 이벤트 유형의 일반적인
기본 동작은
click 이벤트 유형의 기본 동작과 같다.
| 유형 | mousedown
|
|---|---|
| 인터페이스 | MouseEvent |
| 버블링 | 예 |
| 취소 가능 | 예 |
| 합성 | 예 |
| 컨텍스트 (신뢰할 수 있는 이벤트) |
사용자 에이전트는 포인팅 장치 버튼이 요소 위에서 눌릴 때 이 이벤트를 디스패치해MUST 한다.
| 유형 | mouseenter
|
|---|---|
| 인터페이스 | MouseEvent |
| 버블링 | 아니요 |
| 취소 가능 | 아니요 |
| 합성 | 아니요 |
| 컨텍스트 (신뢰할 수 있는 이벤트) |
|
사용자 에이전트는
포인팅 장치가 요소 또는 그 자손 요소 중 하나의 경계 안으로 이동할 때
이 이벤트를 디스패치해MUST 한다. 또한 사용자 에이전트는
요소 또는 그 자손 중 하나가 이동하여 주 포인팅 장치 아래에 위치하게 될 때
이 이벤트를 디스패치해MUST 한다. 이 이벤트 유형은 mouseover와 유사하지만
버블링되지 않으며, 포인팅 장치가 요소에서 그 자손 요소 중 하나의 경계로
이동할 때는 디스패치되어MUST NOT 한다는 점에서 다르다.
이 이벤트 유형과 CSS
:hover 의사 클래스 [CSS2] 사이에는 유사점이 있다.
mouseleave 이벤트 유형도 참조한다.
| 유형 | mouseleave
|
|---|---|
| 인터페이스 | MouseEvent |
| 버블링 | 아니요 |
| 취소 가능 | 아니요 |
| 합성 | 아니요 |
| 컨텍스트 (신뢰할 수 있는 이벤트) |
|
사용자 에이전트는
포인팅 장치가 요소와 그 모든 자손 요소의 경계 밖으로 이동할 때
이 이벤트를 디스패치해MUST 한다. 또한 사용자
에이전트는 요소 또는 그 자손 중 하나가 이동하여 더 이상
주 포인팅 장치 아래에 있지 않게 될 때 이 이벤트를 디스패치해MUST 한다.
이 이벤트 유형은 mouseout과 유사하지만
버블링되지 않으며, 포인팅 장치가 요소와 모든 자식 요소의 경계를
떠날 때까지 디스패치되어MUST NOT 한다는 점에서 다르다.
이 이벤트 유형과 CSS
:hover 의사 클래스 [CSS2] 사이에는 유사점이 있다.
mouseenter 이벤트 유형도 참조한다.
| 유형 | mousemove
|
|---|---|
| 인터페이스 | MouseEvent |
| 버블링 | 예 |
| 취소 가능 | 예 |
| 합성 | 예 |
| 컨텍스트 (신뢰할 수 있는 이벤트) |
사용자 에이전트는
포인팅 장치가 요소 위에서 이동할 때 이 이벤트를
디스패치해MUST 한다. 포인팅 장치가 이동하는 동안의 이벤트
발생 빈도는 구현, 장치 및
플랫폼에 따라 다르지만, 지속적인 포인터 장치 이동에서는 각 마우스 이동마다
단일 이벤트만 발생시키는 대신 연속된 여러 mousemove 이벤트를
발생시키는 것이 SHOULD 좋다. 구현은
응답성과 성능의 균형을 맞추기 위한 최적의 빈도를 결정하는 것이 권장된다.
브라우저와 같은 일부 구현 환경에서는 사용자가
드래그 작업을 시작했고(예: 마우스 버튼이 눌려 있음) 포인팅
장치가 사용자 에이전트의 경계를 벗어난 경우에도
mousemove 이벤트가 계속 발생할 수 있다.
이 이벤트는 이전에 DOM 레벨 2 Events에서 취소할 수 없는 것으로 명시되었지만, 사용자 에이전트 간 기존 상호운용성을 반영하기 위해 변경되었다.
| 유형 | mouseout
|
|---|---|
| 인터페이스 | MouseEvent |
| 버블링 | 예 |
| 취소 가능 | 예 |
| 합성 | 예 |
| 컨텍스트 (신뢰할 수 있는 이벤트) |
|
사용자 에이전트는
포인팅 장치가 요소의 경계 밖으로 이동하거나 요소가 이동하여 더 이상
주 포인팅 장치 아래에 있지 않게 될 때 이 이벤트를 디스패치해MUST 한다.
이 이벤트 유형은 mouseleave와 유사하지만
버블링되며, 포인팅 장치가 요소에서 그 자손 요소 중 하나의 경계로
이동할 때 디스패치되어MUST 한다는 점에서 다르다.
mouseover 이벤트 유형도 참조한다.
| 유형 | mouseover
|
|---|---|
| 인터페이스 | MouseEvent |
| 버블링 | 예 |
| 취소 가능 | 예 |
| 합성 | 예 |
| 컨텍스트 (신뢰할 수 있는 이벤트) |
|
사용자 에이전트는
포인팅 장치가 요소의 경계 안으로 이동하거나 요소가 이동하여
주 포인팅 장치 아래에 위치하게 될 때 이 이벤트를 디스패치해MUST 한다.
이 이벤트 유형은 mouseenter와 유사하지만
버블링되며, 같은 이벤트
리스너 인스턴스의
대상인 조상 요소를 가진 요소의 경계
안으로
포인터 장치가 이동할 때 디스패치되어MUST 한다는 점에서 다르다.
mouseout 이벤트 유형도 참조한다.
| 유형 | mouseup
|
|---|---|
| 인터페이스 | MouseEvent |
| 버블링 | 예 |
| 취소 가능 | 예 |
| 합성 | 예 |
| 컨텍스트 (신뢰할 수 있는 이벤트) |
사용자 에이전트는 포인팅 장치 버튼이 요소 위에서 놓일 때 이 이벤트를 디스패치해MUST 한다.
브라우저와 같은 일부 구현 환경에서는 포인팅 장치가
사용자 에이전트의 경계를 벗어난 경우에도
mouseup 이벤트가 디스패치될 수 있다.
예를 들어 사용자가 마우스 버튼을 누른 상태에서 드래그 작업을 시작한 경우이다.
휠은 하나 이상의 공간 차원에서 회전할 수 있으며 포인터 장치와 연결될 수 있는 장치이다. 좌표계는 환경 구성에 따라 달라진다.
사용자의 환경은 수직 스크롤을 y축을 따른 회전과, 수평 스크롤을 x축을 따른 회전과, 확대/축소를 z축을 따른 회전과 연결하도록 구성되어 있을 수 있다.
WheelEvent
객체의 deltaX, deltaY 및 deltaZ 속성은
각각의 축을 따라 픽셀, 줄 또는 페이지 단위로 측정한 값을 나타낸다.
보고되는 측정값은 환경별 알고리즘이 휠 장치의 실제 회전/이동을
적절한 값과 단위로 변환한 후 제공된다.
사용자의 환경 설정은 휠 장치의 실제 회전/이동을 서로 다른 방식으로 해석하도록
사용자 정의할 수 있다.
일반적인 톱니형
마우스 휠을 한 번 움직이면 162픽셀의 측정값이 생성될 수 있다
(162는 단지 예시 값이며 실제 값은 사용자 에이전트의 현재 화면
크기에 따라 달라질 수 있다).
그러나 사용자는 기본 환경 설정을 변경하여 마우스 휠의 속도를 높이고
이 수치를 증가시킬 수 있다.
또한 일부 마우스 휠 소프트웨어는 가속(휠을 더 빠르게
회전/이동할수록 각 측정값의 델타가 커짐) 또는 서브픽셀 회전
측정까지 지원할 수 있다.
이 때문에 저자는 한 사용자 에이전트에서 주어진 회전량이
모든 사용자 에이전트에서 동일한 델타 값을 생성한다고 가정할 수 없다.
deltaX, deltaY 및 deltaZ 속성 값의 부호(양수 또는 음수)는
실제 휠 장치의 움직임이 동일한 방향으로 회전/이동하는 동안
wheel 이벤트가 여러 번 디스패치되더라도
일관되어MUST 한다.
사용자 에이전트가 wheel 이벤트의 기본 동작으로 스크롤하는 경우
델타의
부호는 양의 X, Y 및 Z축이 각각 문서의 가장 오른쪽 가장자리,
가장 아래쪽 가장자리 및 가장 먼 깊이(사용자에서 멀어지는 방향)를 향하는 오른손 좌표계에 따라
주어지는 것이 SHOULD 좋다.
개별 사용자 에이전트는 환경과 하드웨어 구성에 따라 휠에서 동일한 물리적 사용자 상호작용을 서로 다르게 해석할 수 있다. 예를 들어 트랙패드 가장자리를 위에서 아래로 수직으로 스와이프하는 동작은 페이지를 아래로 스크롤하거나 페이지를 위로 패닝하기 위한 휠 동작으로 해석될 수 있다(즉, 각각 양수 또는 음수 deltaY 값이 생성될 수 있다).
사용자 에이전트는 첫 번째 휠 이벤트가 발생할 때 휠 이벤트 트랜잭션을 생성MUST 하여, 구현별 시간 범위 내의 모든 후속 휠 이벤트가 동일한 요소를 대상으로 할 수 있도록 해야 한다. 휠 이벤트 트랜잭션은 하나의 사용자 제스처와 연결된 일련의 휠 이벤트이다. 휠 이벤트 트랜잭션은 그룹의 첫 번째 휠 이벤트가 발생할 당시의 최상위 이벤트 대상인 연결된 이벤트 대상을 가져MUST 한다.
스크롤 가능한 요소를 대상으로 하는 일련의 휠 이벤트가 자식 요소 위쪽에서 시작되면, 동일한 사용자 제스처에 대한 이후 이벤트는 자식 요소 위에서 발생할 수 있다.
WheelEvent 인터페이스는 wheel 이벤트와 관련된 특정 컨텍스트
정보를 제공한다.
WheelEvent 인터페이스의 인스턴스를
생성하려면 WheelEvent 생성자를 사용하고 선택적인 WheelEventInit 딕셔너리를 전달한다.
WebIDLdictionary WheelEventInit : MouseEventInit {
double deltaX = 0.0;
double deltaY = 0.0;
double deltaZ = 0.0;
unsigned long deltaMode = 0;
boolean momentum = false;
};
[Exposed=Window]
interface WheelEvent : MouseEvent {
constructor(DOMString type, optional WheelEventInit eventInitDict = {});
// DeltaModeCode
const unsigned long DOM_DELTA_PIXEL = 0x00;
const unsigned long DOM_DELTA_LINE = 0x01;
const unsigned long DOM_DELTA_PAGE = 0x02;
readonly attribute double deltaX;
readonly attribute double deltaY;
readonly attribute double deltaZ;
readonly attribute unsigned long deltaMode;
readonly attribute boolean momentum;
};
DOM_DELTA_PIXELDOM_DELTA_LINEDOM_DELTA_PAGEdeltaX
wheel
이벤트의 기본 동작이 스크롤인 사용자 에이전트에서는, 이벤트가 취소되지 않았을 때
스크롤할 x축 방향의 측정값(픽셀, 줄 또는 페이지 단위)이 값이어MUST 한다.
그렇지 않은 경우 이는 휠 장치의 x축 주위 움직임에 대한
구현별 측정값(픽셀, 줄 또는 페이지 단위)이다.
이 속성의 초기화되지 않은
값은
0.0이어MUST 한다.
deltaY
wheel
이벤트의 기본 동작이 스크롤인 사용자 에이전트에서는, 이벤트가 취소되지 않았을 때
스크롤할 y축 방향의 측정값(픽셀, 줄 또는 페이지 단위)이 값이어MUST 한다.
그렇지 않은 경우 이는 휠 장치의 y축 주위 움직임에 대한
구현별 측정값(픽셀, 줄 또는 페이지 단위)이다.
이 속성의 초기화되지 않은
값은
0.0이어MUST 한다.
deltaZ
wheel
이벤트의 기본 동작이 스크롤인 사용자 에이전트에서는, 이벤트가 취소되지 않았을 때
스크롤할 z축 방향의 측정값(픽셀, 줄 또는 페이지 단위)이 값이어MUST 한다.
그렇지 않은 경우 이는 휠 장치의 z축 주위 움직임에 대한
구현별 측정값(픽셀, 줄 또는 페이지 단위)이다.
이 속성의 초기화되지
않은 값은
0.0이어MUST 한다.
WheelEvent
객체의 deltaZ 속성을 초기화한다.
이 속성의 상대적인 양수 값(deltaX 및 deltaY 속성도 마찬가지)은
X, Y 및 Z축이 각각 문서의 가장 오른쪽 가장자리, 가장 아래쪽 가장자리,
가장 먼 깊이(사용자에서 멀어지는 방향)를 향하는
오른손 좌표계에 의해 주어진다.
음의 상대 값은 각각 반대 방향이다.
deltaModedeltaMode 속성은
델타 값의
측정 단위를 나타낸다.
기본값은 DOM_DELTA_PIXEL(픽셀)이다.
이 속성은 델타 값의 측정 단위를 나타내기 위해 DOM_DELTA 상수 중 하나로 설정되어MUST 한다. 정확한 측정 방식은 장치, 운영체제 및 애플리케이션 구성에 따라 달라진다.
이 속성의 초기화되지
않은 값은
0이어MUST 한다.
momentum사용자가 물리적인 스크롤 상호작용을 끝낸 후
(예: 플링 후 트랙패드에서 손가락을 뗀 경우)
스크롤 관성을 시뮬레이션하기 위해 플랫폼이 이 이벤트를 합성했다면
이 속성은 true여야 하고,
그렇지 않으면 false여야 한다.
이 속성의 초기화되지
않은 값은
false이어MUST 한다.
| 유형 | wheel |
|---|---|
| 인터페이스 | WheelEvent |
| 버블링 | 예 |
| 취소 가능 | 경우에 따라 다름 |
| 합성 | 예 |
| 컨텍스트 (신뢰할 수 있는 이벤트) |
|
사용자 에이전트는 마우스 휠이
어떤 축을 중심으로 회전했거나, 동등한 입력 장치
(예: 마우스 볼, 특정 태블릿 또는 터치패드 등)가
이러한 동작을 에뮬레이션했을 때 이 이벤트를 디스패치해MUST 한다. 플랫폼과 입력 장치에 따라
대각선 휠 델타는 0이
아닌 여러 축을 가진 하나의
wheel 이벤트로 전달되거나, 0이 아닌 각 축마다 별도의
wheel 이벤트로 전달될 MAY 있다.
wheel 이벤트 유형의 일반적인 기본
동작은 표시된 양만큼 문서를 스크롤(또는 일부 경우 확대/축소)하는 것이다.
이 이벤트가 취소되면 구현은 문서를 스크롤하거나 확대/축소해MUST NOT 하며
(또는 이 이벤트 유형과 연결된 다른 구현별 기본 동작을 수행해서는 안 된다).
휠 이벤트에서 preventDefault를 호출하면
스크롤을 방지하거나 중단할 수 있다. 최대의 스크롤 성능을 위해
사용자 에이전트는 스크롤과 관련된 각 휠 이벤트가 취소되는지 확인하기 위해
처리될 때까지 기다리지 않을 수 있다. 이런 경우 사용자 에이전트는
cancelable 속성이 false인 wheel 이벤트를 생성하여
preventDefault로 스크롤을 방지하거나 중단할 수 없음을
나타내는 것이 좋다. 그렇지 않으면 cancelable은 true가 된다.
특히 사용자 에이전트가 이벤트에 대해
비수동 리스너가 없음을
관찰하는 경우에는 취소할 수 없는
wheel 이벤트만 생성하는 것이 좋다.
이 섹션은 비규범적이다.
다음은 저자가 이 명세의 일부 API를 어떻게 사용할 수 있는지 보여 주는 기본 예제이다. 더 구체적인 예제는 이 문서의 관련 섹션에서 제공한다.
/* 포인터 이벤트 또는 기존 터치/마우스 중 하나에 바인딩 */
if (window.PointerEvent) {
// 포인터 이벤트가 지원되면 포인터 이벤트만 수신한다
target.addEventListener("pointerdown", function(e) {
// 필요한 경우 e.pointerType에 따라 별도의 로직을 적용한다
// 서로 다른 터치/펜/마우스 동작에 대해
...
});
...
} else {
// 기존 터치/마우스 이벤트 핸들러
target.addEventListener('touchstart', function(e) {
// 호환성 마우스 이벤트 및 click을 방지한다
e.preventDefault();
...
});
...
target.addEventListener('mousedown', ...);
...
}
// 키보드 처리를 위한 추가 이벤트 리스너
...
window.addEventListener("pointerdown", detectInputType);
function detectInputType(event) {
switch(event.pointerType) {
case "mouse":
/* 마우스 입력 감지 */
break;
case "pen":
/* 펜/스타일러스 입력 감지 */
break;
case "touch":
/* 터치 입력 감지 */
break;
default:
/* pointerType이 비어 있음(감지할 수 없음)
또는 UA별 사용자 정의 유형 */
}
}
<div style="position:absolute; top:0px; left:0px; width:100px;height:100px;"></div>
<script>
window.addEventListener("pointerdown", checkPointerSize);
function checkPointerSize(event) {
event.target.style.width = event.width + "px";
event.target.style.height = event.height + "px";
}
</script>
const event1 = new PointerEvent("pointerover",
{ bubbles: true,
cancelable: true,
composed: true,
pointerId: 42,
pointerType: "pen",
clientX: 300,
clientY: 500
});
eventTarget.dispatchEvent(event1);
let pointerEventInitDict =
{
bubbles: true,
cancelable: true,
composed: true,
pointerId: 42,
pointerType: "pen",
clientX: 300,
clientY: 500,
};
const p1 = new PointerEvent("pointermove", pointerEventInitDict);
pointerEventInitDict.clientX += 10;
const p2 = new PointerEvent("pointermove", pointerEventInitDict);
pointerEventInitDict.coalescedEvents = [p1, p2];
const event2 = new PointerEvent("pointermove", pointerEventInitDict);
eventTarget.dispatchEvent(event2);
<div style="position:absolute; top:0px; left:0px; width:100px;height:100px;"></div>
<script>
window.addEventListener("pointerdown", assignPenColor);
window.addEventListener("pointermove", assignPenColor);
const colorMap = new Map();
function assignPenColor(event) {
const uniqueId = event.persistentDeviceId;
// 고유 ID가 존재하는지 확인한다.
if (uniqueId == 0) {
return;
}
// 장치에 색상이 할당되었는지 확인한다.
if (map.has(uniqueId)) {
return;
}
// 장치에 색상을 할당한다.
let newColor = getNewColor();
map.set(uniqueId, newColor);
return newColor;
}
function getNewColor() {
/* 어떤 색상 값을 반환한다 */
}
</script>
이 부록에서는 포인터 이벤트 구현의 보안 및 개인정보 보호 고려사항을 논의한다. 논의는 이 명세에서 정의한 이벤트 모델, API 및 이벤트의 구현으로 직접 발생하는 보안 및 개인정보 보호 문제로 한정한다.
이 명세에서 정의한 많은 이벤트 유형은 사용자 동작에 응답하여 디스패치된다. 이로 인해 악의적인 이벤트 리스너가 사용자가 일반적으로 기밀로 간주할 정보에 접근할 수 있다. 예를 들어 페이지와 상호작용하는 동안 사용자의 마우스/스타일러스/손가락이 이동한 정확한 경로/움직임 등이 있다.
포인터 이벤트에는 사용자의 장치에서 지원되는 경우 펜 입력을 잡고 있는 각도 또는 기울기, 접촉 표면의 형상, 스타일러스나 터치스크린에 가해지는 압력과 같은 추가 정보가 포함된다. 각도, 기울기, 형상 및 압력에 관한 정보는 사용자의 장치에 있는 센서와 직접 관련되므로 이 명세는 오리진이 이러한 센서에 접근할 수 있도록 한다.
이 센서 데이터와 사용된 입력 메커니즘 유형(마우스, 터치, 펜)을 판단하는 기능은 사용자 또는 사용자의 장치 및 환경의 특성을 추론하는 데 사용될 수 있다. 이러한 추론된 특성과 장치/환경 정보 자체도 민감할 수 있다. 예를 들어 악의적인 사이트가 사용자가 보조 기술을 사용하고 있는지 추가로 추론할 수 있게 할 수 있다. 또한 이 정보는 사용자 프로필을 구축하거나 특정 사용자를 "핑거프린팅"하고 추적하려는 목적으로 잠재적으로 사용될 수 있다.
완화책으로 사용자 에이전트는 사용자가 특정 센서 데이터 (예: 각도, 기울기, 압력)에 대한 접근을 비활성화할 수 있는 기능을 포함하거나, 사용자의 명시적인 동의 후에만 이를 사용할 수 있도록 하는 것을 고려할 수 있다.
이 명세는 저자가 "예측된 이벤트"에 접근할 수 있는 방법을 정의한다. 이 명세 자체는 사용자 에이전트가 예측에 사용해야 하는 알고리즘을 정의하지 않는다. 명세 저자는 알고리즘이 사용자가 현재 수행 중인 제스처와 관련된 이전 포인터 이벤트에만 의존할 것으로 예상한다. 예측 알고리즘의 구체적인 구현이 서로 다른 사이트에 걸친 사용자의 전체 상호작용 기록과 같은 추가 데이터에 의존하지 않도록 보장하는 것은 사용자 에이전트의 책임이다. 이러한 데이터는 사용자에 대한 민감한 정보를 드러내거나 사용자를 "핑거프린팅"하고 추적하는 데 사용될 수 있기 때문이다.
이러한 고려사항 외에도 작업 그룹은 이 명세가 다음과 같다고 본다:
이 섹션은 비규범적이다.
buttons 속성 값이 0이 아닌 상태. 마우스의 경우 이는
장치에서 적어도 하나의 버튼이 눌린 상태이다. 터치의 경우 디지타이저와 물리적으로 접촉한 상태이다.
펜의 경우 펜이 디지타이저와 물리적으로 접촉했거나 호버 중 적어도 하나의 버튼이 눌린 상태이다.pointerId로 식별됨)가
문서 내에서 추가 이벤트를 생성할 가능성이 있다면 해당 포인터는 여전히 활성 상태로 간주된다. 예:
WheelEvent 인터페이스를 지원하는 입력 장치
(예: 마우스 휠 또는 터치패드)의 물리적 움직임에 응답하여 사용자 에이전트가 페이지를
스크롤하거나 확대/축소할 것으로 예상되는 양(픽셀, 줄 또는 페이지 단위). 델타 값(예: deltaX, deltaY 또는 deltaZ 속성)은 현재 deltaMode 속성의 컨텍스트에서 해석해야 한다.
휠(또는 다른 장치)의 물리적 움직임과 델타가 양수인지 음수인지의
관계는 환경과 장치에 따라 달라진다. 그러나 사용자 에이전트가 기본 동작으로 스크롤하는 경우
델타의
부호는 양의 X, Y 및 Z축이 각각 문서의 가장 오른쪽
가장자리, 가장 아래쪽 가장자리 및 가장 먼 깊이(사용자에서 멀어지는 방향)를 향하는
오른손 좌표계에 의해 주어진다.
측정 가능한 속성은 실수 또는 넓은 도메인의 정수를 사용하여 표현되는
연속적인 포인터 센서 데이터와 관련된 값을 나타낸다. 포인터 이벤트에서는 width,
height, pressure,
tangentialPressure, tiltX, tiltY, twist,
altitudeAngle, azimuthAngle 및 Mouse Event 모델 속성인
screenX, screenY, clientX, clientY가
측정 가능한 속성이다.
반면 pointerId, pointerType,
isPrimary 및
Mouse Event 모델 속성인 button, buttons, ctrlKey,
shiftKey, altKey, metaKey는 센서 데이터와 관련되지
않으므로 측정 가능한 속성으로 간주되지 않는다.
WheelEvent 인터페이스를 사용하는 입력 장치의 점진적
변화를 나타내는 표시. 일부 장치에서는 이것이 휠의 실제 회전일 MAY 있으며, 다른 장치에서는 평평한 표면을 따른 이동 또는 특정 버튼에
가해지는 압력일
MAY 있다.
히트 테스트기능을 사용하여 대상을 결정한다. 히트 테스트와 스태킹 순서에 관한 구체적인 세부 사항은 호스트 언어를 참조한다.
이 섹션은 규범적이다. 다음 기능은 폐기되었으며 레거시 소프트웨어와의 호환성이 필요한 사용자 에이전트만 구현하는 것이 좋다. [UIEvents]의 레거시 이벤트 초기화자도 참조한다.
WebIDLpartial interface MouseEvent {
};
initMouseEvent(typeArg)MouseEvent 객체의 속성을 초기화한다.
이 메서드는 UIEvent.initUIEvent()와 동일하게 동작한다.
initMouseEvent 메서드는 폐기되었지만 널리 배포된
구현과의 하위 호환성을 위해 지원된다.
initEvent()
메서드를 참조한다.
initEvent()
메서드를 참조한다.
initEvent()
메서드를 참조한다.
view를 지정한다.
이 값은 null일 MAY 있다.
detail을 지정한다.
screenX를 지정한다.
screenY를 지정한다.
clientX를 지정한다.
clientY를 지정한다.
ctrlKey를 지정한다.
altKey를 지정한다.
shiftKey를 지정한다.
metaKey를 지정한다.
button을 지정한다.
relatedTarget을 지정한다.
이 값은
null일 MAY 있다.
많은 분이 제안과 권고를 제공해 주셨으며 그중 일부는 이 문서에 반영되었다. 진심으로 감사드린다. 그룹 의장은 다음의 전·현직 그룹 구성원 및 참가자의 기여에 감사를 표한다: Mustaq Ahmed, Arthur Barstow, Ben Boyle, Matt Brubeck, Rick Byers, Marcos Cáceres, Cathy Chan, Bo Cupp, Domenic Denicola, Ted Dinklocker, Adam Ettenberger, Robert Flack, Dave Fleck, Mike Fraser, Ella Ge, Olga Gerchikov, Scott González, Kartikaya Gupta, Dominique Hazael-Massieux, Philippe Le Hégaret, Hayato Ito, Patrick Kettner, Patrick H. Lauke, Scott Low, Sangwhan Moon, Masayuki Nakano, Olli Pettay, Addison Phillips, Alan Pyne, Antoine Quint, Jacob Rossi, Kagami Sascha Rosylight, Doug Schepers, Ming-Chou Shih, Brenton Simpson, Dave Tapuska, Liviu Tinta, Asir Vedamuthu, Lan Wei, Jeffrey Yasskin, Navid Zolghadr.
과거에 마우스 및 휠 이벤트를 관리해 주신 분들께 감사드린다: Gary Kacmarcik, Travis Leithead 및 수년에 걸친 여러 기여자.
이 모델의 초판을 개척하는 데 도움을 주신 분들, 특히 다음 분들께 특별히 감사드린다: Charu Chandiram, Peter Freiling, Nathan Furtwangler, Thomas Olsen, Matt Rakow, Ramu Ramanathan, Justin Rogers, Jacob Rossi, Reed Townsend 및 Steve Wright.
이 섹션은 비규범적이다.
다음은 [PointerEvents3] 명세와 비교한, 이 명세의 각 공개 버전 사이의 실질적이고 주요한 편집 변경 사항에 대한 정보 제공용 요약이다. 이 명세의 편집자 초안의 전체 개정 이력을 참조한다.
WebIDLdictionary PointerEventInit : MouseEventInit {
long pointerId = 0;
double width = 1;
double height = 1;
float pressure = 0;
float tangentialPressure = 0;
long tiltX;
long tiltY;
long twist = 0;
double altitudeAngle;
double azimuthAngle;
DOMString pointerType = "";
boolean isPrimary = false;
long persistentDeviceId = 0;
sequence<PointerEvent> coalescedEvents = [];
sequence<PointerEvent> predictedEvents = [];
};
[Exposed=Window]
interface PointerEvent : MouseEvent {
constructor(DOMString type, optional PointerEventInit eventInitDict = {});
readonly attribute long pointerId;
readonly attribute double width;
readonly attribute double height;
readonly attribute float pressure;
readonly attribute float tangentialPressure;
readonly attribute long tiltX;
readonly attribute long tiltY;
readonly attribute long twist;
readonly attribute double altitudeAngle;
readonly attribute double azimuthAngle;
readonly attribute DOMString pointerType;
readonly attribute boolean isPrimary;
readonly attribute long persistentDeviceId;
[SecureContext] sequence<PointerEvent> getCoalescedEvents();
sequence<PointerEvent> getPredictedEvents();
};
partial interface Element {
undefined setPointerCapture (long pointerId);
undefined releasePointerCapture (long pointerId);
boolean hasPointerCapture (long pointerId);
};
partial interface mixin GlobalEventHandlers {
attribute EventHandler onpointerover;
attribute EventHandler onpointerenter;
attribute EventHandler onpointerdown;
attribute EventHandler onpointermove;
[SecureContext] attribute EventHandler onpointerrawupdate;
attribute EventHandler onpointerup;
attribute EventHandler onpointercancel;
attribute EventHandler onpointerout;
attribute EventHandler onpointerleave;
attribute EventHandler ongotpointercapture;
attribute EventHandler onlostpointercapture;
};
partial interface Navigator {
readonly attribute long maxTouchPoints;
};
dictionary MouseEventInit : EventModifierInit {
long screenX = 0;
long screenY = 0;
long clientX = 0;
long clientY = 0;
short button = 0;
unsigned short buttons = 0;
EventTarget? relatedTarget = null;
};
[Exposed=Window]
interface MouseEvent : UIEvent {
constructor(DOMString type, optional MouseEventInit eventInitDict = {});
readonly attribute long screenX;
readonly attribute long screenY;
readonly attribute long clientX;
readonly attribute long clientY;
readonly attribute long layerX;
readonly attribute long layerY;
readonly attribute boolean ctrlKey;
readonly attribute boolean shiftKey;
readonly attribute boolean altKey;
readonly attribute boolean metaKey;
readonly attribute short button;
readonly attribute unsigned short buttons;
readonly attribute EventTarget? relatedTarget;
boolean getModifierState(DOMString keyArg);
};
dictionary WheelEventInit : MouseEventInit {
double deltaX = 0.0;
double deltaY = 0.0;
double deltaZ = 0.0;
unsigned long deltaMode = 0;
boolean momentum = false;
};
[Exposed=Window]
interface WheelEvent : MouseEvent {
constructor(DOMString type, optional WheelEventInit eventInitDict = {});
// DeltaModeCode
const unsigned long DOM_DELTA_PIXEL = 0x00;
const unsigned long DOM_DELTA_LINE = 0x01;
const unsigned long DOM_DELTA_PAGE = 0x02;
readonly attribute double deltaX;
readonly attribute double deltaY;
readonly attribute double deltaZ;
readonly attribute unsigned long deltaMode;
readonly attribute boolean momentum;
};
partial interface MouseEvent {
// Deprecated in this specification
undefined initMouseEvent(DOMString typeArg,
optional boolean bubblesArg = false,
optional boolean cancelableArg = false,
optional Window? viewArg = null,
optional long detailArg = 0,
optional long screenXArg = 0,
optional long screenYArg = 0,
optional long clientXArg = 0,
optional long clientYArg = 0,
optional boolean ctrlKeyArg = false,
optional boolean altKeyArg = false,
optional boolean shiftKeyArg = false,
optional boolean metaKeyArg = false,
optional short buttonArg = 0,
optional EventTarget? relatedTargetArg = null);
};
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in: