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 Working Group이 권고안 트랙을 사용하여 작업 초안으로 발행하였다.
작업 초안으로 발행되었다는 사실이 W3C와 그 회원들의 승인을 의미하지는 않는다.
이 문서는 초안 문서이며 언제든지 다른 문서로 갱신, 대체 또는 폐기될 수 있다. 이 문서를 진행 중인 작업 이외의 것으로 인용하는 것은 부적절하다.
이 문서는 W3C 특허 정책에 따라 운영되는 그룹에 의해 작성되었다. W3C는 이 그룹의 산출물과 관련하여 이루어진 모든 특허 공개의 공개 목록을 유지하며, 해당 페이지에는 특허 공개 지침도 포함되어 있다. 어떤 개인이 자신이 보유한 실제 지식에 비추어 그 개인이 필수 청구항을 포함한다고 믿는 특허를 알고 있는 경우, 그 개인은 W3C 특허 정책 제6절에 따라 해당 정보를 공개해야 한다.
이 문서는 2025년 8월 18일 W3C 절차 문서의 적용을 받는다.
이 절은 비규범적이다.
오늘날 대부분의 [HTML] 콘텐츠는 마우스 입력과 함께 사용되거나 및/또는 마우스 입력을 위해 설계된다. 입력을 사용자 정의 방식으로 처리하는 콘텐츠는 일반적으로 [UIEVENTS] Mouse Events에 맞춰 코드를 작성한다. 그러나 오늘날의 더 새로운 컴퓨팅 장치는 터치스크린과 펜 입력을 포함하여 다른 형태의 입력을 통합하고 있다. 이러한 각 입력 형태를 개별적으로 처리하기 위한 이벤트 유형이 제안되어 왔다. 그러나 이러한 접근 방식은 새 입력 유형에 대한 지원을 추가할 때 불필요한 로직 중복과 이벤트 처리 오버헤드를 유발하는 경우가 많다. 이는 콘텐츠가 하나의 장치 유형만 염두에 두고 작성될 때 호환성 문제를 자주 만든다. 또한 기존의 마우스 기반 콘텐츠와의 호환성을 위해 대부분의 사용자 에이전트는 모든 입력 유형에 대해 Mouse Events를 발생시킨다. 이 때문에 Mouse Event가 실제 마우스 장치를 나타내는 것인지, 아니면 호환성을 위해 다른 입력 유형에서 생성된 것인지 모호해지며, 두 장치 유형 모두에 동시에 맞춰 코드를 작성하기 어렵게 된다.
여러 입력 유형에 맞춰 코드를 작성하는 비용을 줄이고, 위에서 설명한 Mouse Events의 모호성에도 도움을 주기 위해, 이 사양은 포인터라고 하는 더 추상적인 형태의 입력을 정의한다. 포인터는 마우스 커서, 펜, 터치(멀티터치 포함), 또는 기타 포인팅 입력 장치가 화면에 만든 임의의 접촉점일 수 있다. 이 모델을 사용하면 사용자가 어떤 하드웨어를 가지고 있는지와 상관없이 잘 동작하는 사이트와 애플리케이션을 더 쉽게 작성할 수 있다. 장치별 처리가 필요한 시나리오를 위해, 이 사양은 이벤트를 생성한 장치 유형을 검사하기 위한 속성도 정의한다. 주요 목표는 장치 간 포인터 입력에 대한 저작을 더 쉽게 해 주는 단일 이벤트 및 인터페이스 집합을 제공하면서도, 향상된 경험을 위해 필요한 경우에만 장치별 처리를 허용하는 것이다.
또 하나의 핵심 목표는 다중 스레드 사용자 에이전트가 스크립트 실행에 의해 차단되지 않고, 패닝 및 줌을 위한 직접 조작 동작(예를 들어 터치스크린에서 손가락이나 스타일러스를 사용하는 경우)을 처리할 수 있게 하는 것이다.
이 사양은 다양한 포인터 입력을 위한 통합 이벤트 모델을 정의하지만, 이 모델은 키보드나 키보드와 유사한 인터페이스와 같은 다른 입력 형태(예를 들어 터치스크린 전용 장치에서 실행되어, 사용자가 포커스 가능한 컨트롤과 요소를 순차적으로 탐색할 수 있게 하는 스크린 리더 또는 유사한 보조 기술)는 다루지 않는다. 사용자 에이전트가 이러한 인터페이스에 대한 응답으로 포인터 이벤트도 생성하도록 선택할 수는 있지만, 이 시나리오는 이 사양에서 다루지 않는다.
우선적으로 저자는 focus, blur 및
click과 같은 고수준 이벤트에 응답하여 모든 형태의
입력에 대해 동등한 기능을 제공하는 것이 권장된다. 그러나 (Pointer Events와 같은) 저수준 이벤트를 사용하는 경우,
저자는 모든 유형의 입력이 지원되도록 보장하는 것이
권장된다. 키보드와 키보드 유사 인터페이스의 경우, 이를 위해 명시적인 키보드 이벤트 처리를 추가해야 할 수 있다.
자세한 내용은 Keyboard Accessible
[WCAG22]을 참조하라.
일반적인 포인터 입력을 처리하기 위한 이벤트는 마우스의 이벤트와 매우 비슷하다. pointerdown,
pointermove, pointerup, pointerover, pointerout 등이 있다. 이는 콘텐츠를
Mouse Events에서 Pointer Events로 쉽게 이전할 수 있게 한다.
Pointer Events는 Mouse Events에 있는 일반적인 모든 속성(클라이언트 좌표,
대상 요소, 버튼 상태 포함)을 제공하며, 압력, 접촉 기하, 기울기와 같은 다른 형태의 입력을 위한 새 속성도 추가로 제공한다.
저자는 의미가 있는 경우 여러 입력 유형 간에 로직을 공유하도록 Pointer Events에 맞춰 쉽게 코드를 작성할 수 있으며,
최상의 경험을 얻기 위해 필요한 경우에만 특정 입력 유형에 맞게 사용자 정의할 수 있다.
Pointer Events는 다양한 입력 장치에서 비롯되지만, 다른 장치별 이벤트 집합에서 생성되는 것으로 정의되지는 않는다. 호환성을 위해 가능하고 권장되기는 하지만, 이 사양은 다른 장치별 이벤트 (예: 마우스 이벤트 또는 터치 이벤트)가 지원되어야 한다고 요구하지 않는다. 사용자 에이전트는 다른 어떤 장치 이벤트도 지원하지 않고 포인터 이벤트만 지원할 수 있다. 마우스 전용 이벤트에 맞춰 작성된 콘텐츠와의 호환성을 위해, 이 사양은 마우스가 아닌 장치의 포인터 입력을 기반으로 호환성 마우스 이벤트를 생성하는 방법을 설명하는 선택적 절을 제공한다.
이 사양은 ( [TOUCH-EVENTS]에 정의된) Touch Events와 Pointer Events를 모두 지원하는 사용자 에이전트의 예상 동작에 대한 조언을 제공하지 않는다. 이 두 사양의 관계에 대한 자세한 내용은 Touch Events Community Group을 참조하라.
비규범으로 표시된 절뿐 아니라, 이 사양의 모든 저작 지침, 다이어그램, 예제 및 참고는 비규범적이다. 이 사양의 그 밖의 모든 것은 규범적이다.
이 문서의 핵심 단어 MAY, MUST, MUST NOT, OPTIONAL, 및 SHOULD는 여기에 표시된 것처럼 모두 대문자로 나타날 때, 그리고 그 경우에만, BCP 14 [RFC2119] [RFC8174]에 설명된 대로 해석되어야 한다.
이 절은 비규범적이다.
다음은 이 사양의 일부 API가 저자에 의해 어떻게 사용될 수 있는지를 보여 주는 기본 예제이다. 더 구체적인 추가 예제는 이 문서의 관련 절에서 제공된다.
/* Pointer Events 또는 기존 touch/mouse 중 하나에 바인딩 */
if (window.PointerEvent) {
// Pointer Events가 지원되면 pointer 이벤트만 수신한다
target.addEventListener("pointerdown", function(e) {
// 필요한 경우 e.pointerType을 기반으로 별도의 로직을 적용한다
// 서로 다른 touch/pen/mouse 동작에 대해
...
});
...
} else {
// 기존 touch/mouse 이벤트 핸들러
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>
마우스 이벤트 모듈은 [HTML401]의 onclick,
ondblclick, onmousedown, onmouseup, onmouseover,
onmousemove, 및 onmouseout 속성에서 유래한다. 이 이벤트 모듈은 마우스나 트랙볼과 같은
포인팅 입력 장치와 함께 사용하도록 특별히 설계되었다.
DOM Level 2에서 도입되었으며, 이 사양에서 수정되었다.
MouseEvent 인터페이스는 Mouse 이벤트와 관련된 구체적인 문맥
정보를 제공한다.
중첩된 요소의 경우, 마우스 이벤트는 항상 가장 깊게 중첩된 요소를 대상으로 한다.
대상 요소의 조상은 이벤트 버블링을 사용하여 그 자손 요소 내에서 발생하는 마우스 이벤트에 대한 알림을 얻을 수 있다.
MouseEvent 인터페이스의 인스턴스를 만들려면, 선택적인
MouseEventInit 딕셔너리를 전달하여 MouseEvent 생성자를 사용한다.
initMouseEvent를 사용하여 MouseEvent 객체를 초기화할 때,
구현은 다른 좌표(예: DOM Level 0 구현 또는 기타 독점 속성에서 노출되는 대상 좌표, 예를 들어
pageX)를 계산하기 위해 클라이언트 좌표 clientX와 clientY를 사용할 수 있다.
WebIDL[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이벤트가 발생한 수평 좌표로, 화면 좌표계의 원점을 기준으로 한다.
이 속성의 초기화되지 않은 값은
MUST 0이어야 한다.
screenY이벤트가 발생한 수직 좌표로, 화면 좌표계의 원점을 기준으로 한다.
이 속성의 초기화되지 않은 값은
MUST 0이어야 한다.
clientX이벤트가 발생한 수평 좌표로, 이벤트와 연결된 뷰포트를 기준으로 한다.
이 속성의 초기화되지 않은 값은
MUST 0이어야 한다.
clientY이벤트가 발생한 수직 좌표로, 이벤트와 연결된 뷰포트를 기준으로 한다.
이 속성의 초기화되지 않은 값은
MUST 0이어야 한다.
layerX조상 요소 중 가장 가까운 요소에서의 수평 오프셋이다. 해당 요소는 쌓임 맥락이거나, 위치 지정된 요소이거나, 쌓임 맥락을 페인팅할 때 위치 지정 단계에서 페인팅된다.
이 속성의 초기화되지 않은 값은
MUST 0이어야 한다.
layerY조상 요소 중 가장 가까운 요소에서의 수직 오프셋이다. 해당 요소는 쌓임 맥락이거나, 위치 지정된 요소이거나, 쌓임 맥락을 페인팅할 때 위치 지정 단계에서 페인팅된다.
이 속성의 초기화되지 않은 값은
MUST 0이어야 한다.
ctrlKey
KeyboardEvent의 ctrlKey
속성을 참조하라.
이 속성의 초기화되지 않은 값은
MUST false이어야 한다.
shiftKey
KeyboardEvent의 shiftKey
속성을 참조하라.
이 속성의 초기화되지 않은 값은
MUST false이어야 한다.
altKey
KeyboardEvent의 altKey
속성을 참조하라.
이 속성의 초기화되지 않은 값은
MUST false이어야 한다.
metaKey
KeyboardEvent의 metaKey
속성을 참조하라.
이 속성의 초기화되지 않은 값은
MUST false이어야 한다.
button
마우스 버튼을 누르거나 놓아서 발생한 마우스 이벤트 동안, button은 어떤 포인터
장치 버튼의 상태가 변경되었는지를 나타내는 데
MUST 사용되어야 한다.
button 속성의 값은 다음과 같아야
MUST 한다:
0은 장치의 주 버튼(일반적으로 왼쪽 버튼 또는 단일 버튼 장치의 유일한 버튼으로,
사용자 인터페이스 컨트롤을 활성화하거나 텍스트를 선택하는 데 사용됨) 또는 초기화되지 않은 값을 나타내야
MUST 한다.
1은 보조 버튼(일반적으로 마우스 휠과 결합된 가운데 버튼)을 나타내야
MUST 한다.
2는 부 버튼(일반적으로 컨텍스트 메뉴를 표시하는 데 자주 사용되는 오른쪽 버튼)을 나타내야
MUST 한다.
3은 X1(뒤로) 버튼을 나타내야 MUST 한다.
4는 X2(앞으로) 버튼을 나타내야 MUST 한다.
일부 포인팅 장치는 더 많은 버튼 상태를 제공하거나 시뮬레이션하며, 2보다 크거나
0보다 작은 값은 이러한 버튼을 나타내는 데
MAY 사용될 수 있다.
button 값은 마우스 버튼을 누르거나 놓아서
발생하지 않은
이벤트에 대해서는 갱신되지 않는다. 이러한 시나리오에서는 값 0을 왼쪽 버튼으로
해석하지 말고, 기본값으로 해석하도록 주의하라.
이 속성의 초기화되지 않은 값은
MUST 0이어야 한다.
buttons
모든 마우스 이벤트 동안, buttons는 현재 눌려 있는 마우스 버튼의
조합을 비트마스크로 표현하여 나타내는 데 MUST 사용되어야 한다.
이름은 비슷하지만, buttons 속성과 button 속성의 값은 매우
다르다. button 값은
mousedown / mouseup 이벤트 핸들러 동안 유효하다고
가정되는 반면, buttons 속성은 신뢰된
MouseEvent 객체가 (디스패치되는 동안)
임의의 마우스 버튼 상태를 반영한다. 이는 "현재 활성 버튼 없음" 상태(0)를 나타낼 수 있기 때문이다.
buttons 속성의 값은 다음과 같아야
MUST 한다:
0은 현재 활성인 버튼이 없음을 나타내야 MUST 한다.
1은 장치의 주 버튼(일반적으로 왼쪽 버튼 또는 단일 버튼 장치의 유일한 버튼으로,
사용자 인터페이스 컨트롤을 활성화하거나 텍스트를 선택하는 데 사용됨)을 나타내야
MUST 한다.
2는 존재하는 경우 부 버튼(일반적으로 컨텍스트 메뉴를 표시하는 데 자주 사용되는
오른쪽 버튼)을 나타내야 MUST 한다.
4는 보조 버튼(일반적으로 마우스 휠과 결합된 가운데 버튼)을 나타내야
MUST 한다.
일부 포인팅 장치는 더 많은 버튼을 제공하거나 시뮬레이션한다. 이러한 버튼을 나타내기 위해, 값은
각 후속 버튼마다 두 배가 되어야 MUST 한다(이진 계열
8, 16, 32, ... ).
버튼 값들의 임의 집합의 합은 고유한 숫자이므로, 콘텐츠 저자는 비트 연산을 사용하여
현재 몇 개의 버튼이 눌려 있는지와 어떤 버튼인지, 장치의 임의 개수 마우스 버튼에 대해
판별할 수 있다. 예를 들어 값 3은 왼쪽 버튼과 오른쪽 버튼이 현재 모두
눌려 있음을 나타내고, 값 5는 왼쪽 버튼과 가운데 버튼이 현재 모두
눌려 있음을 나타낸다.
이 속성의 초기화되지 않은 값은
MUST 0이어야 한다.
relatedTarget
이벤트 유형에 따라 UI 이벤트와 관련된 보조 EventTarget을 식별하는 데
사용된다.
이 속성의 초기화되지 않은 값은
MUST null이어야 한다.
키 값을 사용하여 수정자의 상태를 질의한다.
수정자 키이고 그 수정자가 활성화되어 있으면 true를 반환하고,
그렇지 않으면 false를 반환한다.
DOMString
keyArgKeyboardEvent의
getModifierState()
메서드를 참조하라.
WebIDLdictionary MouseEventInit : EventModifierInit {
long screenX = 0;
long screenY = 0;
long clientX = 0;
long clientY = 0;
short button = 0;
unsigned short buttons = 0;
};
screenX
screenX 속성의 MouseEvent 객체를 사용자 화면에서의 마우스 포인터의 원하는
수평 상대 위치로 초기화한다.
이벤트 객체를 주어진 마우스 위치로 초기화하더라도 사용자의 마우스 포인터가 초기화된 위치로 이동해서는 안 된다.
screenY
screenY 속성의 MouseEvent 객체를 사용자 화면에서의 마우스 포인터의 원하는 수직
상대 위치로 초기화한다.
이벤트 객체를 주어진 마우스 위치로 초기화하더라도 사용자의 마우스 포인터가 초기화된 위치로 이동해서는 안 된다.
clientX
clientX 속성의 MouseEvent 객체를 사용자의 브라우저 클라이언트 창을 기준으로 한
마우스 포인터의 원하는
수평 위치로 초기화한다.
이벤트 객체를 주어진 마우스 위치로 초기화하더라도 사용자의 마우스 포인터가 초기화된 위치로 이동해서는 안 된다.
clientY
clientY 속성의 MouseEvent 객체를 사용자의 브라우저 클라이언트 창을 기준으로 한
마우스 포인터의 원하는 수직
위치로 초기화한다.
이벤트 객체를 주어진 마우스 위치로 초기화하더라도 사용자의 마우스 포인터가 초기화된 위치로 이동해서는 안 된다.
button
button 속성의 MouseEvent 객체를 마우스 버튼(들)의 원하는 상태를 나타내는
숫자로
초기화한다.
값 0은 주 마우스 버튼을 나타내는 데 사용되고, 1은 보조/가운데 마우스 버튼을 나타내는 데 사용되며, 2는 오른쪽 마우스 버튼을 나타내는 데 사용된다. 2보다 큰 숫자도 가능하지만, 이 문서에서는 지정하지 않는다.
buttons
buttons 속성의 MouseEvent 객체를 활성으로 간주되어야 하는 마우스 버튼(들) 중
하나 또는 그 이상을 나타내는 숫자로 초기화한다.
buttons 속성은 비트 필드이다.
마스크 값 1을 비트 필드 값에 적용했을 때 참이면 주 마우스 버튼이 눌린 것이다. 마스크 값 2를
비트 필드 값에 적용했을 때 참이면 오른쪽 마우스 버튼이 눌린 것이다. 마스크 값 4를
비트 필드 값에 적용했을 때 참이면 보조/가운데 버튼이 눌린 것이다.
JavaScript에서, 오른쪽(2) 버튼과 가운데 버튼(4)이 동시에 눌린 것처럼
buttons
속성을 초기화하려면, buttons 값은 다음 중 하나로 할당할 수 있다:
{ buttons: 2 | 4 }
또는:
{ buttons: 6 }
relatedTarget
relatedTarget는
( mouseover 또는 mouseenter 이벤트의 경우) 마우스 포인터가 방금 경계를 떠난
요소, 또는 ( mouseout 또는 mouseleave 또는 focusout 이벤트의 경우) 마우스 포인터가
경계 안으로 들어가고 있는 요소로 초기화되어야 한다. 다른 이벤트의 경우, 이 값은 할당할 필요가 없다
(그리고 기본값은 null이 된다).
구현은 마우스 이벤트를 생성할 때 현재 클릭 횟수를 유지해야 MUST 한다. 이는 특정 시간 안에 포인팅 장치 버튼이 연속으로 클릭된 횟수를 나타내는 음이 아닌 정수여야 MUST 한다. 그 횟수가 재설정되는 지연 시간은 환경 구성에 따라 다르다.
이 절의 알고리즘은 네이티브 플랫폼 OS가 다음을 제공한다고 가정한다:
이러한 이벤트에 대해, OS는 다음 정보를 제공할 수 있다:
이 절은 개정이 필요하다.
일반적으로, Event 인터페이스의 생성자, 또는 Event 인터페이스에서 상속된 인터페이스의 생성자가 호출되면,
[DOM]에 설명된 단계를 따라야 한다. 그러나 MouseEvent 인터페이스는 Event 객체의 키
수정자의 내부 상태, 구체적으로 getModifierState()
메서드를 사용하여 질의되는 내부 상태를 초기화하기 위한 추가 딕셔너리 멤버를 제공한다. 이 절은 이러한 선택적 수정자
상태를 사용하여 새 MouseEvent 객체를 초기화하기 위한
[DOM] 단계를 보완한다.
아래 알고리즘을 사용하여 MouseEvent, 또는 이러한 객체에서 파생된
객체를 생성하기 위한 목적상,
모든 MouseEvent 및 파생 객체는
내부
키 수정자 상태를 가지며, 이는 [UIEvents-Key]의
Modifier Keys 표에 설명된
키 수정자 이름을 사용하여 설정하고 가져올 수 있다.
다음 단계는 [DOM]에 정의된 이벤트 생성 알고리즘을 보완한다:
Event가 MouseEvent 객체이거나 그로부터 파생된 객체이고,
생성자에 EventModifierInit
인수가 제공되었다면, 다음 하위 단계를 실행한다:
EventModifierInit
인수에 대해, 딕셔너리 멤버가 문자열 "modifier"로 시작한다면,
키 수정자 이름을 딕셔너리
멤버 이름에서 접두사 "modifier"를 제외한 것으로 두고, 해당 키 수정자 이름과 일치하는 Event 객체의 내부 키
수정자 상태를 해당 값으로 설정한다.
이 절은 개정이 필요하다.
UA는 전체 사용자 에이전트에 대해 공유되는 다음 값을 유지해야 한다.
마우스 버튼의 현재 상태를 추적하는 마우스 버튼 비트마스크.
UA는 Window에 대해 공유되는 다음 값을 유지해야 한다.
MouseEvent를 보낸 마지막 Element를 추적하는
마지막
마우스 요소 값(초기값은 undefined).
가장 최근의 마우스 이벤트가 전송되었을 때 마지막 마우스 요소의 조상
Element들의 스냅샷을 포함하는
마지막
마우스 DOM 경로 값(초기값은 비어 있음).
이 절은 개정이 필요하다.
MouseEvent는 다양한 수정자 키의 상태를 추적하는 데 사용되는 다음
내부 플래그를 가진다:
shift 플래그,
control
플래그,
alt 플래그,
altgraph
플래그,
및 meta 플래그.
이러한 플래그는 마우스 이벤트가 발생한 시점에 해당 수정자 키가 눌려 있었다면 설정된다.
이 절은 개정이 필요하다.
elementFromPoint()를
pos와 함께 반환한다(pos에 있는 가장 앞쪽 DOM 요소)
inert 또는 disabled
요소를 고려하기 위해, 이는 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에 대해 네이티브 mouse up 처리 직후에 이를 호출해야 한다.
이 절은 개정이 필요하다.
EventTarget으로 둔다
screenX가
정수 값이 아니면, 반올림한다.screenY가
정수 값이 아니면, 반올림한다.PointerEvents와 반올림된 좌표를 사용하는 브라우저에 대한 정보는 pointerevents/100을 참조하라.
모든 "기본 동작"은 디스패치 중 대상에 대한 활성화 동작 알고리즘을 트리거하여 처리된다. 따라서 여기서 이를 처리할 필요는 없다. 그러나 기존 사양이 disabled/css-pointer-events/inert/...를 처리하는지 확인해야 한다.
HTMLelement.click()을 처리하려면, native =
null 및 target = HTMLelement로 이 알고리즘을 호출한다.
키보드로 시작된 클릭을 처리하려면, native = null 및 target = 현재 포커스된 요소로 이 알고리즘을 호출한다.
이 절은 개정이 필요하다.
이는 더블 클릭을 생성하는 마우스 클릭에 대해 handle native mouse click 직후에 호출되어야 한다.
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.
섀도 DOM 요소에 대한 호환성을 확인한다. Chrome/Linux는 이 이벤트를 요소와 섀도 루트에서 발생시킨다.
이 사양에 정의된 특정 마우스 이벤트는 서로에 대해 정해진 순서로 발생해야 MUST 한다. 다음은 포인팅 장치의 커서가 요소 위로 이동할 때 발생해야 MUST 하는 이벤트 순서를 보여 준다:
| # | 이벤트 유형 | 요소 | 참고 |
|---|---|---|---|
| 1 | mousemove
|
||
| 포인팅 장치가 요소 A 안으로 이동한다... | |||
| 2 | mouseover
|
A | |
| 3 | mouseenter
|
A | |
| 4 | mousemove
|
A | 여러 mousemove 이벤트
|
| 포인팅 장치가 요소 A 밖으로 이동한다... | |||
| 5 | mouseout
|
A | |
| 6 | mouseleave
|
A |
포인팅 장치가 요소 A 안으로 이동한 다음, 중첩된 요소 B 안으로 이동하고 다시 밖으로 이동할 때, 다음 이벤트 순서가 발생해야 MUST 한다:
| 이벤트 유형 | 요소 | 참고 | |
|---|---|---|---|
| 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로 표시된 세 요소가 모두 웹 페이지에서 같은 크기와 절대 위치를 가진다. 요소 C는 B의 자식이고, B는 DOM에서 A의 자식이다:
포인팅 장치가 요소 스택 밖에서 C로 표시된 요소로 이동한 뒤 다시 밖으로 이동할 때, 다음 일련의 이벤트가 발생해야 MUST 한다:
| 이벤트 유형 | 요소 | 참고 | |
|---|---|---|---|
| 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
|
OPTIONAL, 여러 이벤트, 일부 제한 |
| 3 | mouseup
|
|
| 4 | click
|
|
| 5 | mousemove
|
OPTIONAL, 여러 이벤트, 일부 제한 |
| 6 | mousedown
|
|
| 7 | mousemove
|
OPTIONAL, 여러 이벤트, 일부 제한 |
| 8 | mouseup
|
|
| 9 | click
|
|
| 10 | dblclick
|
mousedown과 mouseup 이벤트 사이에서, 여전히 click 또는 dblclick
이벤트를 발생시키면서 허용되는 지연 시간, 정도, 거리 및 mousemove 이벤트의 수는 구현, 장치 및
플랫폼에 따라 다르다.
이러한 허용 오차는 손 떨림과 같은 신체적 장애가 있는 사용자가 포인팅 장치와 상호작용할 때
도움을 줄 수 있다.
각 구현은 적절한 히스테리시스
허용 오차를 결정하지만, 일반적으로 관련 mousedown
및
mouseup 이벤트의 이벤트 대상이 같고 중간에 mouseout 또는
mouseleave 이벤트가 끼어들지 않은 경우,
click 및 dblclick
이벤트를 발생시키는 것이 좋으며 SHOULD, 관련 mousedown 및
mouseup 이벤트 대상이
서로 다를 때는 가장 가까운 공통 포함 조상에서 click 및
dblclick 이벤트를 발생시키는 것이 좋다
SHOULD.
mousedown 이벤트가 HTML 문서의 body
요소를 대상으로 하고, 해당 mouseup 이벤트가
문서 요소를 대상으로 했다면,
click 이벤트는 가장 가까운 공통 포함 조상이므로
문서
요소에 디스패치된다.
대상(예: 대상 요소)이 마우스 이벤트 순서 중에 DOM에서 제거되면, 그 순서의 나머지 이벤트는 해당 요소에서 발생해서는 MUST NOT 안 된다.
mousedown 이벤트의 결과로 대상 요소가 DOM에서 제거되면,
해당 요소에 대해서는 mouseup, click, 또는 dblclick에 대한 이벤트나 기본
활성화 이벤트가 디스패치되지 않는다. 그러나 mouseup 이벤트는 초기 대상 요소가 제거된 후
마우스에 노출되는 요소에서 여전히 디스패치된다. 마찬가지로, mouseup 이벤트의
디스패치 중에 대상 요소가 DOM에서 제거되면,
click 및 그 이후의 이벤트는 디스패치되지 않는다.
| 유형 | auxclick
|
|---|---|
| 인터페이스 | PointerEvent
|
| 동기 / 비동기 | 동기 |
| 버블링 | 예 |
| 신뢰된 대상 | Element |
| 취소 가능 | 예 |
| 합성됨 | 예 |
| 기본 동작 | 다양함 |
| 문맥 (신뢰된 이벤트) |
|
사용자가 주가 아닌 포인터 버튼을 누르고 놓거나, 그러한 동작을 시뮬레이션하는 방식으로
포인터를 활성화할 때, 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을
애플리케이션에서 사용할 수 없을 수도 있다는 점에 유의하라.
더 자세한 설명은 예제 7을 참조하라.
myDiv.addEventListener("contextmenu", function(e) {
// 이 호출은 컨텍스트 메뉴가 표시되지 않도록 보장하여
// 페이지가 이벤트를 수신하는 것을 방해하지 않게 한다.
e.preventDefault();
});
myDiv.addEventListener("auxclick", function(e) {
if (e.button === 2) {
// 앱 내부에서 사용자 정의 컨텍스트 메뉴를 여는 것처럼
// 오른쪽 버튼 클릭을 처리하기 위한 다른 작업을 수행한다.
}
});
| 유형 | click
|
|---|---|
| 인터페이스 | PointerEvent
|
| 동기 / 비동기 | 동기 |
| 버블링 | 예 |
| 신뢰된 대상 | Element |
| 취소 가능 | 예 |
| 합성됨 | 예 |
| 기본 동작 | 다양함 |
| 문맥 (신뢰된 이벤트) |
|
사용자가 주 포인터 버튼을 누르고 놓거나, 그러한 동작을 시뮬레이션하는 방식으로
포인터를 활성화할 때, 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 |
| 동기 / 비동기 | 동기 |
| 버블링 | 예 |
| 신뢰된 대상 | Element |
| 취소 가능 | 예 |
| 합성됨 | 예 |
| 기본 동작 | 없음 |
| 문맥 (신뢰된 이벤트) |
|
사용자 에이전트는
포인팅 장치의 주 버튼이 요소 위에서 두 번 클릭될 때 이 이벤트를 디스패치해야
MUST 한다. 더블 클릭의 정의는 환경 구성에 따라 달라지지만,
mousedown, mouseup, 및 dblclick 사이에서 이벤트 대상은 같아야
MUST 한다. 클릭과 더블 클릭이 동시에 발생하면 이 이벤트
유형은 이벤트 유형 click 이후에 디스패치되어야 MUST
하며, 그렇지 않으면 이벤트 유형
mouseup 이후에 디스패치되어야 한다.
click 이벤트와 마찬가지로, dblclick 이벤트는
주 포인터 버튼에 대해서만 발생해야 한다. 보조 버튼은 dblclick 이벤트를 발생시켜서는
MUST NOT 안 된다.
click 이벤트 유형과 마찬가지로, 기본 동작은
dblclick 이벤트 유형의 경우 이벤트의 대상과
button
또는 buttons 속성의 값에 따라 달라진다. dblclick 이벤트 유형의 일반적인
기본 동작은
click 이벤트 유형의 기본 동작과 일치한다.
| 유형 | mousedown
|
|---|---|
| 인터페이스 | MouseEvent |
| 동기 / 비동기 | 동기 |
| 버블링 | 예 |
| 신뢰된 대상 | Element |
| 취소 가능 | 예 |
| 합성됨 | 예 |
| 기본 동작 | 다양함: 드래그/드롭 작업 시작, 텍스트 선택 시작, 스크롤/팬 상호작용 시작 (지원되는 경우 가운데 마우스 버튼과 함께) |
| 문맥 (신뢰된 이벤트) |
|
| 유형 | mouseenter
|
|---|---|
| 인터페이스 | MouseEvent |
| 동기 / 비동기 | 동기 |
| 버블링 | 아니요 |
| 신뢰된 대상 | Element |
| 취소 가능 | 아니요 |
| 합성됨 | 아니요 |
| 기본 동작 | 없음 |
| 문맥 (신뢰된 이벤트) |
|
mouseover와
비슷하지만, 버블링하지 않으며, 포인터 장치가 요소에서 그 자손 요소 중 하나의
경계 위로 이동할 때 디스패치되어서는 MUST NOT 안 된다는 점이 다르다.
이 이벤트 유형과 CSS
:hover 의사 클래스 [CSS2]
사이에는
유사점이 있다.
mouseleave 이벤트 유형도 참조하라.
| 유형 | mouseleave
|
|---|---|
| 인터페이스 | MouseEvent |
| 동기 / 비동기 | 동기 |
| 버블링 | 아니요 |
| 신뢰된 대상 | Element |
| 취소 가능 | 아니요 |
| 합성됨 | 아니요 |
| 기본 동작 | 없음 |
| 문맥 (신뢰된 이벤트) |
|
mouseout과
비슷하지만, 버블링하지 않으며, 포인팅 장치가 요소의 경계와 그 모든 자식의
경계를 떠날 때까지 디스패치되어서는 MUST NOT 안 된다는 점이 다르다.
이 이벤트 유형과 CSS
:hover 의사 클래스 [CSS2]
사이에는
유사점이 있다.
mouseenter 이벤트 유형도 참조하라.
| 유형 | mousemove
|
|---|---|
| 인터페이스 | MouseEvent |
| 동기 / 비동기 | 동기 |
| 버블링 | 예 |
| 신뢰된 대상 | Element |
| 취소 가능 | 예 |
| 합성됨 | 예 |
| 기본 동작 | 없음 |
| 문맥 (신뢰된 이벤트) |
|
mousemove
이벤트를
발생시키는 것이 좋다 SHOULD. 구현은 응답성과 성능의 균형을 맞추기 위해
최적의 빈도를 결정하는 것이 권장된다.
브라우저와 같은 일부 구현 환경에서는, 사용자가 드래그 작업(예: 마우스 버튼이 눌림)을 시작했고
포인팅 장치가 사용자 에이전트의 경계를 벗어난 경우에도
mousemove 이벤트가 계속 발생할 수 있다.
이 이벤트는 이전에는 DOM Level 2 Events에서 취소 불가능한 것으로 지정되었지만, 사용자 에이전트 간의 기존 상호운용성을 반영하도록 변경되었다.
| 유형 | mouseout
|
|---|---|
| 인터페이스 | MouseEvent |
| 동기 / 비동기 | 동기 |
| 버블링 | 예 |
| 신뢰된 대상 | Element |
| 취소 가능 | 예 |
| 합성됨 | 예 |
| 기본 동작 | 없음 |
| 문맥 (신뢰된 이벤트) |
|
mouseleave와 비슷하지만,
버블링하며, 포인터 장치가 요소에서 그 자손 요소 중 하나의 경계 위로 이동할 때
디스패치되어야 MUST 한다는 점이 다르다.
mouseover 이벤트 유형도 참조하라.
| 유형 | mouseover
|
|---|---|
| 인터페이스 | MouseEvent |
| 동기 / 비동기 | 동기 |
| 버블링 | 예 |
| 신뢰된 대상 | Element |
| 취소 가능 | 예 |
| 합성됨 | 예 |
| 기본 동작 | 없음 |
| 문맥 (신뢰된 이벤트) |
|
mouseenter와 비슷하지만,
버블링하며, 포인터 장치가 동일한 이벤트 리스너 인스턴스에 대한
대상의 조상 요소를 가진 요소의 경계 위로
이동할 때 디스패치되어야 MUST 한다는 점이 다르다.
mouseout 이벤트 유형도 참조하라.
| 유형 | mouseup
|
|---|---|
| 인터페이스 | MouseEvent |
| 동기 / 비동기 | 동기 |
| 버블링 | 예 |
| 신뢰된 대상 | Element |
| 취소 가능 | 예 |
| 합성됨 | 예 |
| 기본 동작 | 없음 |
| 문맥 (신뢰된 이벤트) |
|
브라우저와 같은 일부 구현 환경에서는, 예를 들어 사용자가 마우스 버튼을 누른 상태로
드래그 작업을 시작한 경우처럼 포인팅 장치가 사용자 에이전트의 경계를
벗어났더라도 mouseup 이벤트가 디스패치될 수 있다.
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이벤트를 일으킨 포인터의 고유 식별자이다. 사용자 에이전트는 기본 마우스 포인터에 대해
0 또는 1의 일반적인 pointerId 값을 예약할 수
MAY 있다. -1의 pointerId 값은 예약되어야
MUST 하며, 포인팅 장치가 아닌 것에 의해 생성된 이벤트를 나타내는 데
사용되어야 한다. 그 밖의 모든 포인터에 대해서는, 사용자 에이전트가 pointerId
값을 할당하는 방식에 대해 서로 다른 전략과 접근 방식을 자유롭게 구현할 수 있다. 그러나
[HTML]에 정의된 최상위
브라우징 컨텍스트 안의 모든 활성 포인터는 고유해야 하며, 식별자는 다른 어떤
최상위
브라우징 컨텍스트의 영향도 받아서는 MUST NOT 안 된다(즉, 한
최상위 브라우징 컨텍스트는 포인터가 브라우징 컨텍스트 밖으로 이동해 다른 최상위 브라우징 컨텍스트로
들어갈 때 그 포인터의 pointerId가 같을 것이라고
가정할 수 없다).
사용자 에이전트는
이전 활성 포인터에서 폐기된 pointerId 값을 재활용할 수
MAY 있거나, 특정 포인팅 장치에 대해 항상 같은 pointerId
를 재사용할 수 MAY 있다(예를 들어, 다중 사용자 협업 애플리케이션에서 특정
사용자의 특정 펜/스타일러스 입력을 고유하게 식별하기 위해). 그러나 후자의 경우, 서로 다른 페이지나
도메인 간의 핑거프린팅 및 추적 가능성을 최소화하기 위해, pointerId는 페이지/세션의
수명 동안에만 해당 특정 포인팅 장치와 명시적으로 연결되어야 MUST 하며,
다음에 해당 특정 포인팅 장치가 새 세션에서 다시 사용될 때는 새로운 무작위 pointerId가 선택되어야
MUST 한다.
pointerId 선택
알고리즘은 구현별이다. 저자는 값이 다른 모든 활성 포인터와 고유한 포인터 식별자라는 것 외에
어떤 특정 의미를 전달한다고 가정할 수 없다. 예를 들어, 사용자 에이전트는 활성화되는 순서대로
활성 포인터에 0부터 시작하는 숫자를 단순히 할당할 수 있지만, 이러한 값이
단조 증가한다고 보장되지는 않는다. 특정 포인팅 장치에 대해 같은 pointerId를
재사용할지 여부는 개별 구현에 맡겨져 있으므로, 저자는 이에 의존하지 말고 대신 persistentDeviceId
를 참조하는 것이 강하게 권장된다.
width포인터의 접촉 기하 구조의 너비(X축에서의 크기)이며, CSS 픽셀 단위이다([CSS21]
참조).
이 값은 주어진 포인터에 대해 각 이벤트마다 갱신될 수 MAY 있다. 일반적으로 접촉 기하 구조가 없는 입력(예:
전통적인 마우스) 및
입력의 실제 기하 구조가 하드웨어에 의해 감지되지 않는 경우, 사용자 에이전트는 기본값
1을 반환해야 MUST 한다.
height포인터의 접촉 기하 구조의 높이(Y축에서의 크기)이며, CSS 픽셀 단위이다([CSS21]
참조).
이 값은 주어진 포인터에 대해 각 이벤트마다 갱신될 수 MAY 있다. 일반적으로 접촉 기하 구조가 없는 입력(예:
전통적인 마우스) 및
입력의 실제 기하 구조가 하드웨어에 의해 감지되지 않는 경우, 사용자 에이전트는 기본값
1을 반환해야 MUST 한다.
pressure[0,1] 범위의 포인터 입력의 정규화된 압력이며, 여기서
0과 1은 각각 하드웨어가 감지할 수 있는 최소 및 최대 압력을
나타낸다. 압력을 지원하지 않는 하드웨어 및 플랫폼의 경우, 활성 버튼 상태에서는 값이
0.5이어야
MUST 하며, 그렇지 않으면 0이어야 한다.
tangentialPressure포인터 입력의 정규화된 접선 압력(배럴 압력이라고도 함)으로, 일반적으로 추가 컨트롤(예:
에어브러시 스타일러스의 핑거 휠)에 의해 설정되며 [-1,1] 범위이다. 여기서
0은 컨트롤의 중립 위치이다. 일부 하드웨어는 [0,1] 범위의
양수 값만 지원할 수 있음에 유의하라. 접선 압력을 지원하지 않는 하드웨어 및 플랫폼의 경우 값은
MUST 0이어야 한다.
tiltXY-Z 평면과 트랜스듀서(예: 펜/스타일러스) 축 및 Y축을 모두 포함하는 평면 사이의
평면 각도(도 단위, [-90,90] 범위)이다. 양의
tiltX는 X 값이 증가하는 방향인 오른쪽을 의미한다.
tiltX는 tiltY와 함께 사용되어 디지타이저에 대한 트랜스듀서의
법선으로부터의 기울기를 나타낼 수 있다. 기울기나 각도를 보고하지 않는 하드웨어 및 플랫폼의 경우
값은 MUST 0이어야 한다.
tiltX.
tiltYX-Z 평면과 트랜스듀서(예: 펜/스타일러스) 축 및 X축을 모두 포함하는 평면 사이의
평면 각도(도 단위, [-90,90] 범위)이다. 양의
tiltY는 Y 값이 증가하는 방향인 사용자 쪽을 의미한다.
tiltY는 tiltX와 함께 사용되어 디지타이저에 대한 트랜스듀서의
법선으로부터의 기울기를 나타낼 수 있다. 기울기나 각도를 보고하지 않는 하드웨어 및 플랫폼의 경우
값은 MUST 0이어야 한다.
tiltY.
twist트랜스듀서(예: 펜/스타일러스)가 자신의 주축 주위로 시계 방향으로 회전한 값(도 단위,
[0,359] 범위)이다. twist를 보고하지 않는 하드웨어 및 플랫폼의 경우 값은
MUST 0이어야 한다.
altitudeAngle트랜스듀서(예: 펜/스타일러스)의 고도각(라디안 단위)이며, 범위는
[0,π/2]이다. 여기서 0은 표면(X-Y 평면)과 평행함을,
π/2는 표면에 수직임을 의미한다. 기울기나 각도를 보고하지 않는 하드웨어 및 플랫폼의 경우
값은 MUST π/2이어야 한다.
altitudeAngle의 기본값은 π/2이며,
이는 트랜스듀서가 표면에 수직인 것으로 위치시킨다.
이는 Touch Events - Level
2 사양의
altitudeAngle 속성 정의와 다르며, 그 사양의 기본값은
0이다.
π/4(X-Y
평면에서 45도)의 altitudeAngle 예.azimuthAngle트랜스듀서(예: 펜/스타일러스)의 방위각(라디안 단위)이며, 범위는
[0, 2π]이다. 여기서 0은 캡이 X 값이 증가하는 방향을
가리키는 트랜스듀서(X-Y 평면을 바로 내려다보면 "3시" 방향)를 나타내며, 값은 시계 방향으로
진행할수록 점진적으로 증가한다(π/2는 "6시", π는 "9시",
3π/2는 "12시"). 트랜스듀서가 표면에 완전히 수직일 때
(altitudeAngle이 π/2인 경우), 값은 MUST
0이어야 한다. 기울기나 각도를 보고하지 않는 하드웨어 및 플랫폼의 경우 값은
MUST
0이어야 한다.
π/6
("4시")의 azimuthAngle 예.pointerType이벤트를 일으킨 장치 유형(mouse, pen, touch 등)을 나타낸다. 사용자 에이전트가 마우스,
펜/스타일러스 또는 터치 입력 장치에 대해 포인터 이벤트를 발생시켜야 한다면,
pointerType의 값은 다음 표에 따라야 MUST 한다:
| 포인터 장치 유형 | pointerType 값 |
|---|---|
| 마우스 | mouse |
| 펜 / 스타일러스 | pen |
| 터치 접촉 | touch |
사용자 에이전트가 장치 유형을 감지할 수 없으면, 값은 빈 문자열이어야 MUST 한다. 사용자 에이전트가 위에 나열된 것
이외의 포인터 장치
유형을 지원하는 경우, pointerType 값은 서로 다른 장치 유형의 이름 충돌을 피하기 위해
벤더 접두사를 붙이는 것이 좋다 SHOULD. 향후 사양은 다른 장치 유형에 대한 추가 규범 값을 제공할 수
MAY 있다.
pointerType을 어떻게 사용할 수 있는지에 대한 기본 데모는
예제 2를 참조하라. 또한 개발자는 사용자 에이전트가
자체 사용자 정의 pointerType 값을 구현했을 수 있는 경우 및
pointerType이 단순히 빈 문자열인 상황을 포괄하기 위해 어떤 형태의 기본 처리를
포함해야 한다는 점에 유의하라.
isPrimary포인터가 이 포인터 유형의 기본 포인터를 나타내는지 여부를 나타낸다.
persistentDeviceId포인팅 장치의 고유 식별자이다. 하드웨어가 여러 포인터를 지원하는 경우,
포인팅 장치에서 생성된 포인터 이벤트는 해당 포인터가 세션 전체에서 고유하게 식별 가능한 경우에만
persistentDeviceId를 가져야 MUST 한다.
포인터가 고유하게 식별 가능하면, 해당 포인팅 장치에 할당된
persistentDeviceId는 세션의 나머지 기간 동안 일정하게 유지된다.
0의 persistentDeviceId 값은 예약되어야
MUST 하며, 생성 장치를 식별할 수 없는 이벤트를 나타내는 데 사용되어야 한다.
pointerId와 마찬가지로, 서로 다른 페이지나 도메인 간의
핑거프린팅 및 추적 가능성을 최소화하기 위해,
persistentDeviceId는 페이지/세션의 수명 동안에만 해당 특정 포인팅 장치와 명시적으로
연결되어야 MUST 하며, 다음에 해당 특정 포인팅 장치가 새 세션에서 다시 사용될 때는
새로운 무작위 persistentDeviceId가 선택되어야 MUST 한다.
persistentDeviceId가 포인팅 장치의 모든 포인터 이벤트에서 사용 가능하다고 보장되지는 않는다.
예를 들어, 장치가 pointerdown에
persistentDeviceId가 포함될 만큼 제때 자신의 하드웨어 ID를 디지타이저에 보고하지 않을 수 있다.
이러한 경우 persistentDeviceId는 처음에는 0이었다가 유효한 값으로
변경될 수 있다.
getCoalescedEvents()병합된 이벤트의 목록을 반환하는 메서드이다.
getPredictedEvents()예측된 이벤트의 목록을 반환하는 메서드이다.
PointerEventInit 딕셔너리는 신뢰되지 않은(합성)
포인터 이벤트를 구성하기 위한 메커니즘을 제공하기 위해 PointerEvent 인터페이스의 생성자에서 사용된다.
이는 [UIEVENTS]에 정의된
MouseEventInit 딕셔너리에서 상속한다.
신뢰되지 않은 포인터 이벤트를 발생시키는 방법을 보여 주는 샘플 코드는
예제를 참조하라.
PointerEvent의 이벤트
구성 단계는 PointerEventInit의 coalescedEvents를 병합된 이벤트 목록으로 복제하고,
PointerEventInit의 predictedEvents를 예측된 이벤트 목록으로 복제한다.
PointerEvent 인터페이스는 UI
Events에 정의된 MouseEvent에서 상속한다.
또한 다양한 좌표 속성을 long에서 double로 변경하여 소수 좌표를 허용하는
CSSOM
View Module의 제안된 확장도 유의하라.
이 제안된 확장을
PointerEvent에 대해서는 이미 구현했지만 일반
MouseEvent에 대해서는 구현하지 않은 사용자 에이전트의 경우,
click,
auxclick, 및 contextmenu 이벤트와 관련해 추가 요구사항이 있다.
다중 포인터(예: 멀티터치) 시나리오에서는, isPrimary 속성이 각 포인터
유형별 활성 포인터 집합에서 마스터 포인터를
식별하는 데 사용된다.
pointerType마다 하나씩)가 기본으로 간주된다. 예를 들어, 터치 접촉과
마우스 커서가 동시에 이동하면 둘 다 기본으로 간주되는 포인터를 생성한다.
isPrimary 값이 false인
포인터 이벤트를 발생시킬 수 MAY 있다.e라는 포인터
이벤트를 발생시킨다는 것은, e라는 이벤트를 발생시키되,
PointerEvent 인터페이스 및
속성과 기본 동작에 정의된 대로 속성이 설정된
PointerEvent를 사용하여 발생시키는 것을 의미한다.
이벤트가 gotpointercapture, lostpointercapture,
click,
auxclick 또는 contextmenu 이벤트가 아니면, 이
PointerEvent에 대해 보류 중인 포인터 캡처 처리 단계를
실행한다.
이벤트가 발생되는 대상 결정은 다음과 같이 한다:
targetDocument를 target의 노드 문서 [DOM]로 둔다.
이벤트가 pointerdown, pointermove, 또는 pointerup이면, 이벤트의 활성 문서를
해당 pointerId에 대해
targetDocument로 설정한다.
이벤트가 pointerdown이고, 관련
장치가 직접 조작 장치이며, 대상이 Element이면,
암시적 포인터 캡처에 설명된 대로
이 pointerId에 대한 포인터 캡처 설정을 대상 요소로 수행한다.
이 이벤트를 발생시키기 전에, 사용자
에이전트는
이벤트 순서 보장 [UIEVENTS]을 위해
포인팅 장치가 previousTarget에서 대상으로 이동한 것처럼 대상을 처리하는 것이 좋다
SHOULD. needsOverEvent 플래그가 설정되어 있으면, 대상
요소가 같더라도 pointerover 이벤트가 필요하다.
결정된 대상에 이벤트를 발생시킨다.
결정된 대상을 주어진 포인터의 previousTarget으로 저장하고,
needsOverEvent 플래그를 false로 재설정한다.
어느 시점에서든 previousTarget이 더 이상 연결됨 [DOM] 상태가 아니게 되면,
previousTarget으로 이벤트를 디스패치할 때의 이벤트 경로를 따라 가장 가까운 아직
연결됨 [DOM]
상태인 부모로
previousTarget을 갱신하고,
needsOverEvent 플래그를 true로 설정한다.
이 사양에 정의된 이벤트 유형에 대한 bubbles 및 cancelable 속성과
기본 동작은 다음 표에 나타난다. 이러한 각 이벤트 유형의 세부 사항은
Pointer Event 유형에서 제공된다.
| 이벤트 유형 | 버블링 | 취소 가능 | 기본 동작 |
|---|---|---|---|
pointerover
|
예 | 예 | 없음 |
pointerenter |
아니요 | 아니요 | 없음 |
pointerdown
|
예 | 예 | 다양함: 포인터가 기본일 때, mousedown 이벤트의 모든 기본 동작
이 이벤트를 취소하면 이후의 호환성 마우스 이벤트 발생도 방지된다. |
pointermove
|
예 | 예 | 다양함: 포인터가 기본일 때, mousemove의 모든 기본 동작
|
pointerrawupdate |
예 | 아니요 | 없음 |
pointerup |
예 | 예 | 다양함: 포인터가 기본일 때, mouseup의 모든 기본 동작
|
pointercancel |
예 | 아니요 | 없음 |
pointerout
|
예 | 예 | 없음 |
pointerleave |
아니요 | 아니요 | 없음 |
gotpointercapture |
예 | 아니요 | 없음 |
lostpointercapture |
예 | 아니요 | 없음 |
뷰포트 조작(팬 및 줌) — 일반적으로 직접 조작 상호작용의 결과 — 은 의도적으로 포인터
이벤트의 기본 동작이 아니다. 즉 이러한 동작(예: 터치스크린에서 손가락을 움직인 결과로 페이지를 팬하는 것)은
포인터 이벤트를 취소하여 억제할 수 없다. 대신 저자는 touch-action을 사용하여 문서의
한 영역에 대한 직접 조작 동작을 명시적으로 선언해야 한다.
이벤트 취소에 대한 이 의존성을 제거하면 사용자 에이전트의 성능 최적화가 쉬워진다.
pointerenter 및 pointerleave 이벤트의 경우, composed
[DOM] 속성은 false인 것이 좋다
SHOULD; 위 표의 다른 모든 포인터 이벤트의 경우, 그 속성은
true인 것이 좋다 SHOULD.
위 표의 모든 포인터 이벤트에 대해, detail [UIEVENTS] 속성은 0인 것이 좋다 SHOULD.
fromElement 및
toElement를 노출한다. 우리는 이러한 사용자 에이전트가 PointerEvents에서
이러한 (상속된) 속성 값을 null로 설정하여 저자가 표준화된 대체 속성
(target 및 relatedTarget)을 사용하도록 전환하기를 권장한다.
MouseEvent의 relatedTarget와 마찬가지로,
relatedTarget은 포인터가 방금 떠난 경계를 가진 요소(pointerover 또는
pointerenter 이벤트의 경우), 또는 포인터가 들어가고 있는 경계를 가진 요소
(pointerout 또는 pointerleave 이벤트의 경우)로 초기화되어야 한다.
다른 포인터 이벤트의 경우, 이 값은 기본적으로 null이 된다. 요소가 포인터 캡처를 받으면 해당 포인터에 대한
이후 모든 이벤트는 캡처 요소의 경계 안에 있는 것으로 간주된다는 점에 유의하라.
gotpointercapture
및 lostpointercapture 이벤트의 경우, 위 표에
정의된 속성을 제외한 모든 속성은 사용자 에이전트가
보류 중인 포인터 캡처 처리 단계를 실행하고
gotpointercapture
및 lostpointercapture 이벤트를 발생시키게 한
Pointer Event와 같아야 한다.
사용자 에이전트는
포인터 캡처를 암시적으로 해제할 때뿐 아니라
gotpointercapture
또는 lostpointercapture가 아닌 Pointer
Events를
발생시킬 때, 다음 단계를 실행해야 MUST 한다.
lostpointercapture라는 이름의
포인터 이벤트를 발생시킨다.
gotpointercapture라는 이름의
포인터 이벤트를 발생시킨다.
click,
auxclick, 및 contextmenu 이벤트에 대한 절에 정의된 것처럼,
lostpointercapture 이벤트가
디스패치된 후에도, 대응하는 click, auxclick 또는
contextmenu 이벤트가 있으면 여전히 캡처 대상으로 디스패치된다.
사용자 에이전트는
웹 페이지가 특정 pointerId를 가진 포인터 이벤트를
계속 수신할 가능성이 낮다는 것을 감지하면 포인터 이벤트 스트림을 억제해야
MUST 한다. 다음 시나리오 중 하나가 이 조건을 만족한다(추가 시나리오가
있을 수 MAY 있다):
touch-action CSS
속성에 관한 절을 참조하라.
사용자 에이전트가 포인터 이벤트 스트림을 억제할 수 MAY 있는 다른 시나리오는 다음을 포함한다:
이러한 시나리오를 감지하는 방법은 이 사양의 범위 밖이다.
사용자 에이전트는 포인터 이벤트 스트림을 억제하기 위해 다음 단계를 실행해야 MUST 한다:
pointercancel
이벤트를 발생시킨다.pointerout 이벤트를
발생시킨다.
pointerleave 이벤트를
발생시킨다.
화면 표면을 기준으로 이동했거나 어떤 속성에 변화가 생긴 포인팅 장치는 Pointer Event 유형에 정의된 대로
다양한 이벤트를 발생시킨다. 정지한 포인팅 장치(화면 표면을 기준으로 이동하지도 않았고 어떤 속성에도
변화가 없었던 장치)의 경우, 포인터의 히트 테스트 대상에 영향을 준
레이아웃 변경 이후, 사용자 에이전트는
특정 경계 이벤트를 발생시켜야
MUST 한다. 자세한 내용은 pointerover, pointerenter, pointerout 및 pointerleave를 참조하라. 사용자 에이전트는 성능상의
이유로(예: 경계 이벤트 리스너로 인해 너무 많은 히트 테스트나 레이아웃 변경이 발생하는 것을 피하기 위해)
이러한 경계 이벤트의 발생을 지연할 수 MAY 있다.
pointermove 이벤트를 발생시키지 않는다.Pointer Events는 X-Y 평면을 기준으로 한 트랜스듀서의 방향을 표현하기 위해 서로 보완적인 두
속성 집합을 포함한다: tiltX / tiltY(원래 Pointer Events 사양에서 도입됨) 및
azimuthAngle / altitudeAngle
(Touch Events - Level 2
사양에서 채택됨).
특정 하드웨어 및 플랫폼에 따라, 사용자 에이전트는 화면 평면을 기준으로 한 트랜스듀서 방향에 대해
하나의 값 집합만 수신할 가능성이 높다 — tiltX /
tiltY 또는 altitudeAngle / azimuthAngle. 사용자 에이전트는
이러한 값을 변환하기 위해 다음 알고리즘을 사용해야 MUST 한다.
사용자 에이전트가 azimuthAngle /
altitudeAngle에서 tiltX / tiltY를 계산할 때, 최종 정수 값은
Math.round [ECMASCRIPT] 규칙을 사용하여 반올림하는 것이 좋다
SHOULD.
/* 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;
// azimuth angle 계산
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) {
// azimuth를 계산하기에 정보가 충분하지 않다
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;
}
}
// altitude angle 계산
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 속성을
event로 복사한다
MouseEvent로 둔다TODO.
target으로 둔다MouseEvent로 둔다TODO.
target으로 둔다MouseEvent로 둔다TODO.
target으로 둔다MouseEvent로 둔다TODO.
target으로 둔다MouseEvent로 둔다
이것이 pointermove와 pointerrawupdate를 전송할 수 있는가? 아니면 두 개의 메서드가 필요한가?
pointermove 이벤트가 병합되는 방식을 제대로 정의하려면 무엇이 필요한가?
TODO.
target으로 둔다MouseEvent로 둔다
mousedown 이벤트와 달리, 여러 버튼이 눌렸을 때 pointerdown
이벤트는 중첩되지 않는다.
필드를 PointerEvent로 복사할 수 있도록 MouseEvent가
전달된다.
TODO.
target으로 둔다MouseEvent로 둔다
target으로 둔다MouseEvent로 둔다
mouseup 이벤트와 달리, 여러 버튼이 눌렸을 때 pointerup 이벤트는 중첩되지 않는다.
필드를 PointerEvent로 복사할 수 있도록 MouseEvent가 전달된다.
TODO.
target으로 둔다아래는 이 사양에 정의된 이벤트 유형이다.
기본 포인터의 경우, 이러한 이벤트는(gotpointercapture 및 lostpointercapture 제외) 호환성 마우스 이벤트도 발생시킬 수 있다.
사용자 에이전트는
다음 중 하나가 발생할 때 포인터 이벤트를 발생시키되, pointerover라는 이름으로 발생시켜야
MUST 한다:
pointerdown 이벤트를 호버를 지원하지 않는 장치에 대해 발생시키기 전
(pointerdown 참조).사용자 에이전트는
다음 중 하나가 발생할 때 포인터 이벤트를 발생시키되, pointerenter라는 이름으로 발생시켜야
MUST 한다:
pointerdown 이벤트를 호버를 지원하지 않는 장치에 대해 발생시키기 전
(pointerdown 참조).mouseenter 이벤트,
그리고 [CSS21]에
설명된 CSS :hover 의사 클래스 사이에는 유사점이 있다.
pointerleave 이벤트도
참조하라.
사용자 에이전트는 포인터가 활성 버튼 상태에 들어갈 때 포인터 이벤트를
발생시키되, pointerdown이라는 이름으로 발생시켜야
MUST 한다. 마우스의 경우, 이는 장치가 버튼이 눌리지 않은 상태에서
하나 이상의 버튼이 눌린 상태로 전환될 때이다. 터치의 경우, 이는 디지타이저와 물리적 접촉이 이루어질 때이다.
펜의 경우, 이는 펜이 어떤 버튼도 눌리지 않은 상태에서 디지타이저와 물리적으로 접촉하거나, 호버 중에
버튼이 눌리지 않은 상태에서 하나 이상의 버튼이 눌린 상태로 전환될 때이다.
pointerdown 및 pointerup이 mousedown 및
mouseup과 같은 모든 상황에서 발생하지 않는다는 것을 의미한다. 자세한 내용은 코드형 버튼을
참조하라.
호버를 지원하지 않는 입력 장치의 경우,
사용자
에이전트는 pointerdown 이벤트를
디스패치하기 전에 포인터
이벤트를 발생시키되, pointerover라는 이름으로 발생시키고,
이어서 pointerenter라는 이름의
포인터 이벤트도 발생시켜야 MUST 한다.
pointerdown 이벤트를 취소함으로써 방지할 수 있다
(isPrimary 속성이 true인 경우). 이는 포인터에
PREVENT MOUSE EVENT 플래그를 설정한다. 그러나 이것이
mouseover, mouseenter, mouseout 또는
mouseleave 이벤트의 발생을 방지하지는 않는다는 점에 유의하라.
사용자 에이전트는
포인터가 pointerdown 또는 pointerup 이벤트를 발생시키지 않는 속성을
변경할 때 포인터 이벤트를 발생시키되, pointermove라는 이름으로 발생시켜야
MUST 한다. 여기에는 좌표, 압력, 접선 압력,
기울기, twist, 접촉 기하 구조(width 및 height) 또는 코드형 버튼에 대한 모든
변경이 포함된다.
사용자 에이전트는 pointermove 이벤트의 디스패치를
(예를 들어 성능상의 이유로) 지연할 수 MAY 있다.
병합된 이벤트 정보는 단일 디스패치된 pointermove 이벤트의 getCoalescedEvents 메서드를
통해 노출된다. 이러한 이벤트의 최종 좌표는 이벤트의 대상을 찾는 데 사용되어야 한다.
사용자 에이전트는
포인터가 pointerdown 또는 pointerup 이벤트를 발생시키지 않는 속성을
변경할 때 포인터 이벤트를 발생시키되,
pointerrawupdate라는
이름으로, 그리고 보안 컨텍스트
안에서만 발생시켜야 MUST 한다. 이러한 속성 목록은
pointermove 이벤트를 참조하라.
pointermove와 달리,
사용자 에이전트는 pointerrawupdate 이벤트를
가능한 한 빨리,
그리고 JavaScript가 이벤트를 처리할 수 있는 만큼 자주 디스패치하는 것이 좋다
SHOULD.
pointerrawupdate 이벤트의
target은 pointermove 이벤트와 다를 수 있다.
이는 pointermove 이벤트가
지연되거나 병합될 수 있고, target을 찾는 데 사용되는 이벤트의 최종 위치가 그 병합된
이벤트와 다를 수 있기 때문이다.
같은 pointerId를 가진 다른 pointerrawupdate가 이미 있고 그것이
이벤트
루프에서
아직 디스패치되지 않았다면, 사용자
에이전트는 새 pointerrawupdate를 새 작업을 만드는 대신
그 이벤트와 병합할 수 MAY 있다.
이로 인해 pointerrawupdate가
병합된 이벤트를 가질 수 있으며, 이벤트가 이벤트 루프에서
처리되는 즉시 이들은 모두 하나의 pointerrawupdate 이벤트의
병합된 이벤트로 전달된다.
자세한 내용은 getCoalescedEvents를
참조하라.
pointerrawupdate 및 pointermove의 순서와 관련해,
사용자 에이전트가 플랫폼으로부터 pointerrawupdate와 pointermove 이벤트를 모두 발생시키는 업데이트를
수신했다면, 사용자 에이전트는
대응하는 pointermove보다 먼저
pointerrawupdate 이벤트를 디스패치해야
MUST 한다.
target을 제외하면, 마지막 pointermove
이벤트 이후 디스패치된 모든 pointerrawupdate 이벤트의
병합된 이벤트 목록을
연결한 것은, 다른 이벤트 속성 측면에서 다음 pointermove 이벤트의 병합된 이벤트와
같다.
pointerrawupdate의
속성은 대부분 pointermove와 같지만,
예외적으로
cancelable은 pointerrawupdate에 대해 false여야
MUST 한다.
사용자 에이전트는 호환성 마우스 이벤트를 pointerrawupdate에 대해 발생시키지 않는 것이 좋다
SHOULD.
pointerrawupdate
이벤트에 리스너를 추가하면,
사용자 에이전트의 구현에 따라 웹 페이지의 성능에 부정적인 영향을 줄 수 있다.
대부분의 사용 사례에서는 다른 pointerevent 유형으로 충분하다.
JavaScript가 고빈도 이벤트를 필요로 하고 이를 그만큼 빠르게 처리할 수 있는 경우에만 pointerrawupdate
리스너를 추가하는 것이 좋다.
이러한 경우에는 다른 유형의 포인터 이벤트를 수신할 필요가 없을 가능성이 높다.사용자 에이전트는 포인터가 활성 버튼 상태를 떠날 때 포인터 이벤트를
발생시키되, pointerup이라는 이름으로 발생시켜야
MUST 한다. 마우스의 경우, 이는 장치가 하나 이상의 버튼이 눌린 상태에서
버튼이 눌리지 않은 상태로 전환될 때이다. 터치의 경우, 이는 디지타이저로부터 물리적 접촉이 제거될 때이다.
펜의 경우, 이는 버튼이 눌리지 않은 상태에서 펜이 디지타이저와의 물리적 접촉에서 제거되거나, 호버 중에
하나 이상의 버튼이 눌린 상태에서 버튼이 눌리지 않은 상태로 전환될 때이다.
호버를 지원하지 않는 입력 장치의 경우,
사용자
에이전트는 pointerup 이벤트를
디스패치한 후 포인터
이벤트를 발생시키되, pointerout이라는 이름으로 발생시키고,
이어서 pointerleave라는 이름의
포인터 이벤트도 발생시켜야 MUST 한다.
모든 pointerup 이벤트는 pressure
값이 0이다.
사용자 에이전트는 포인터가 현재 캡처되어 있는 경우에도 포인터 캡처를 암시적으로 해제해야 MUST 한다.
pointerdown 및 pointerup이 mousedown 및
mouseup과 같은 모든 상황에서 발생하지 않는다는 것을 의미한다. 자세한 내용은 코드형 버튼을
참조하라.
사용자 에이전트는 포인터 이벤트 스트림을 억제할 시나리오를 감지하면
포인터 이벤트를 발생시키되, pointercancel이라는 이름으로 발생시켜야
MUST 한다.
pointercancel 이벤트의 다음 속성 값은
같은 pointerId를 가진 마지막으로
디스패치된 포인터 이벤트의 값과 일치해야 MUST 한다: width,
height, pressure, tangentialPressure, tiltX,
tiltY, twist, altitudeAngle, azimuthAngle,
pointerType, isPrimary, 그리고 [UIEVENTS]에서 상속된
좌표. pointercancel 이벤트의
coalescedEvents 및 predictedEvents 목록은 비어 있어야 하며
MUST, 이벤트의 cancelable 속성은
false여야 MUST 한다.
사용자 에이전트는 다음 중 하나가
발생할 때 포인터 이벤트를 발생시키되, pointerout이라는 이름으로 발생시켜야
MUST 한다:
pointerup 이벤트를
호버를 지원하지 않는 장치에 대해 발생시킨 후
(pointerup 참조).
사용자 에이전트는
다음 중 하나가 발생할 때 포인터 이벤트를 발생시키되, pointerleave라는 이름으로 발생시켜야
MUST 한다:
pointerup 이벤트를
호버를 지원하지 않는 장치에 대해 발생시킨 후
(pointerup 참조).
mouseleave 이벤트,
그리고 [CSS21]에
설명된 CSS :hover 의사 클래스 사이에는 유사점이 있다.
pointerenter 이벤트도
참조하라.
사용자 에이전트는
요소가 포인터 캡처를 받을 때 포인터 이벤트를 발생시키되, gotpointercapture라는
이름으로 발생시켜야 MUST 한다. 이 이벤트는 포인터 캡처를 받고 있는 요소에서 발생한다.
해당 포인터의 이후 이벤트는 이 요소에서 발생한다. 포인터 캡처 설정 및 보류 중인 포인터 캡처 처리 절을 참조하라.
사용자 에이전트는
포인터에 대한 포인터 캡처가 해제된 후 포인터 이벤트를 발생시키되, lostpointercapture라는
이름으로 발생시켜야 MUST 한다.
이 이벤트는 캡처가 해제된 후 해당 포인터에 대한 이후 이벤트보다 먼저 발생해야
MUST 한다. 이 이벤트는 포인터 캡처가 제거된 요소에서 발생한다.
해당 포인터에 대한 이후 모든 이벤트는 click,
auxclick, 및 contextmenu 이벤트를 제외하고,
이벤트 대상을 결정하기 위해 일반적인 히트 테스트 메커니즘(이 사양의 범위 밖)을 따른다. 포인터 캡처
해제, 포인터 캡처의 암시적
해제, 및
보류 중인 포인터
캡처 처리 절을 참조하라.
사용자의 환경은 y축을 따른 회전을 세로 스크롤과 연결하고, x축을 따른 회전을 가로 스크롤과 연결하며, z축을 따른 회전을 줌과 연결하도록 구성될 수 있다.
WheelEvent 객체의 deltaX, deltaY,
deltaZ 속성은 각 축을 따라 픽셀, 줄 또는 페이지 단위의 측정값을 나타낸다.
보고되는 측정값은 환경별 알고리즘이 휠 장치의 실제 회전/이동을
적절한 값과 단위로 변환한 뒤 제공된다.
사용자의 환경 설정은 휠 장치의 실제 회전/이동을 서로 다른 방식으로 해석하도록
사용자 정의될 수 있다.
일반적인 홈이 있는
마우스 휠의 한 번 움직임은 162픽셀의 측정값을 생성할 수 있다
(162는 단지 예시 값이며, 실제 값은 사용자 에이전트의 현재 화면
크기에 따라 달라질 수 있다).
그러나 사용자는 기본 환경 설정을 변경하여 마우스 휠을 더 빠르게 만들 수 있고,
이 숫자를 증가시킬 수 있다.
또한 일부 마우스 휠 소프트웨어는 가속(휠이 더 빠르게
회전/이동할수록 각 측정값의 delta가 더 커짐) 또는 서브픽셀 회전
측정값까지 지원할 수 있다.
이 때문에 저자는 어떤 사용자 에이전트에서의 특정 회전량이
모든 사용자 에이전트에서 같은 delta 값을 생성한다고 가정할 수 없다.
wheel 이벤트가 여러 번 디스패치될 때,
deltaX, deltaY 및 deltaZ 속성 값의 부호(양수 또는 음수)는
일관되어야 MUST 한다.
사용자 에이전트가 wheel 이벤트의 기본 동작으로 스크롤한다면,
delta의 부호는
양의 X, Y, Z축이 각각 문서의 가장 오른쪽 가장자리, 가장 아래쪽 가장자리, 그리고 가장 먼
깊이(사용자로부터 멀어지는 방향)를 향하는 오른손 좌표계에 의해 주어지는 것이 좋다
SHOULD.
개별 사용자 에이전트는(환경 및 하드웨어 구성에 따라) 휠에서의 동일한 물리적 사용자 상호작용을 서로 다르게 해석할 수 있다. 예를 들어, 트랙패드 가장자리에서 위에서 아래로 하는 세로 스와이프는 페이지를 아래로 스크롤하려는 휠 동작으로 해석될 수도 있고, 페이지를 위로 팬하려는 휠 동작으로 해석될 수도 있다(즉, 각각 양수 또는 음수 deltaY 값을 결과로 낼 수 있다).
스크롤 가능한 요소를 대상으로 하는 일련의 wheel 이벤트가 자식 요소 위에서 시작하면, 같은 사용자 제스처의 이후 이벤트는 그 자식 요소 위에서 발생할 수 있다.
WheelEvent 인터페이스는
wheel 이벤트와 관련된 특정 문맥 정보를 제공한다.
WheelEvent 인터페이스의 인스턴스를
만들려면, 선택적 WheelEventInit 딕셔너리를
전달하여 WheelEvent 생성자를 사용한다.
WebIDL[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_PAGEdeltaXwheel
이벤트의 기본 동작이 스크롤인 사용자 에이전트에서, 이벤트가 취소되지 않은 경우 이 값은
스크롤될 x축 방향의 측정값(픽셀, 줄 또는 페이지 단위)이어야
MUST 한다. 그렇지 않으면 이는 x축 주위의 휠 장치 움직임에 대한
구현별 측정값(픽셀, 줄 또는 페이지 단위)이다.
이 속성의 초기화되지
않은 값은
0.0이어야 MUST 한다.
deltaYwheel
이벤트의 기본 동작이 스크롤인 사용자 에이전트에서, 이벤트가 취소되지 않은 경우 이 값은
스크롤될 y축 방향의 측정값(픽셀, 줄 또는 페이지 단위)이어야
MUST 한다. 그렇지 않으면 이는 y축 주위의 휠 장치 움직임에 대한
구현별 측정값(픽셀, 줄 또는 페이지 단위)이다.
이 속성의 초기화되지
않은 값은
0.0이어야 MUST 한다.
deltaZwheel
이벤트의 기본 동작이 스크롤인 사용자 에이전트에서, 이벤트가 취소되지 않은 경우 이 값은
스크롤될 z축 방향의 측정값(픽셀, 줄 또는 페이지 단위)이어야
MUST 한다. 그렇지 않으면 이는 z축 주위의 휠 장치 움직임에 대한
구현별 측정값(픽셀, 줄 또는 페이지 단위)이다.
이 속성의 초기화되지
않은 값은
0.0이어야 MUST 한다.
deltaModedeltaMode 속성은 delta 값의 측정 단위에 대한 표시를 포함한다.
기본값은 DOM_DELTA_PIXEL(픽셀)이다.
이 속성은 delta 값의 측정 단위를 나타내기 위해
DOM_DELTA 상수 중 하나로 설정되어야 MUST 한다.
정확한 측정값은 장치, 운영 체제 및 애플리케이션 구성에 따라 다르다.
이 속성의 초기화되지
않은 값은
0이어야 MUST 한다.
momentumtrue여야 하며,
그렇지 않으면 false여야 한다.
이 속성의 초기화되지
않은 값은
false여야 MUST 한다.
WebIDLdictionary WheelEventInit : MouseEventInit {
double deltaX = 0.0;
double deltaY = 0.0;
double deltaZ = 0.0;
unsigned long deltaMode = 0;
boolean momentum = false;
};
아래 정의들은 위에서 이미 해당 속성들이 정의되어 있으므로 중복되는 것처럼 보입니다. 다음을 참조하세요: pointerevents/646.
deltaXdeltaZ 속성을 참조하라.deltaYdeltaZ 속성을 참조하라.deltaZWheelEvent 객체의
deltaZ 속성을 초기화한다.
이 속성(및 deltaX와 deltaY 속성)에 대한 상대적인 양수 값은
X, Y, Z축이 각각 문서의 가장 오른쪽 가장자리, 가장 아래쪽 가장자리,
그리고 가장 먼 깊이(사용자로부터 멀어지는 방향)를 향하는 오른손 좌표계에 의해 주어진다.
음의 상대값은 각각 그 반대 방향이다.
deltaMode
WheelEvent 객체의
deltaMode 속성을 열거 값 0, 1 또는 2로
초기화한다. 이는 휠의 회전이 스크롤을 일으켰을 경우 스크롤된 픽셀 양
(DOM_DELTA_PIXEL), 스크롤된 줄
(DOM_DELTA_LINE), 또는 스크롤된 페이지
(DOM_DELTA_PAGE)를 나타낸다.
momentummomentum 속성을 초기화합니다.
| 유형 | wheel |
|---|---|
| 인터페이스 | WheelEvent |
| 동기 / 비동기 | 비동기 |
| 버블링 | 예 |
| 신뢰된 대상 | Element |
| 취소 가능 | 다양함 |
| 합성됨 | 예 |
| 기본 동작 | 문서를 스크롤(또는 줌)한다 |
| 문맥 (신뢰된 이벤트) |
|
wheel 이벤트로 전달될 수도 있고, 각 0이 아닌 축마다 별도의
wheel 이벤트로 전달될 수도
MAY 있다.
wheel 이벤트 유형의 일반적인
기본 동작은
표시된 양만큼 문서를 스크롤(또는 경우에 따라 줌)하는 것이다.
이 이벤트가 취소되면, 구현은 문서를 스크롤하거나 줌해서는 안 되며
MUST NOT,
이 이벤트 유형과 연결된 다른 어떤 구현별 기본 동작도 수행해서는 안 된다.
wheel 이벤트에서 preventDefault를 호출하면 스크롤을 방지하거나
그 밖의 방식으로 중단할 수 있다. 최대 스크롤 성능을 위해, 사용자 에이전트는
스크롤과 연결된 각 wheel 이벤트가 취소될지 확인하기 위해 처리될 때까지
기다리지 않을 수 있다. 이러한 경우 사용자 에이전트는
cancelable 속성이 false인 wheel 이벤트를 생성하는 것이 좋으며,
이는 preventDefault를 사용하여 스크롤을 방지하거나 중단할 수 없음을 나타낸다.
그렇지 않으면 cancelable은 true가 된다.
특히 사용자 에이전트는 해당 이벤트에 대해
비수동 리스너가 없음을
관찰한 경우, 취소 불가능한 wheel 이벤트만 생성하는 것이 좋다.
다음 절은 포인터 캡처의 설정과 해제를 용이하게 하기 위해 기존 Element 인터페이스에
대한 확장을 설명한다.
WebIDLpartial interface Element {
undefined setPointerCapture (long pointerId);
undefined releasePointerCapture (long pointerId);
boolean hasPointerCapture (long pointerId);
};
setPointerCapture()인수 pointerId로 식별되는 포인터에 대해,
이 메서드가 호출된 요소로 포인터 캡처를 설정한다.
해당 포인터의 이후 이벤트에서는 포인터가 항상 캡처 대상 위에 있는 것처럼 캡처 대상이 일반 히트 테스트
결과를 대체하며, 캡처가 해제될 때까지 항상 이 요소를 대상으로 해야
MUST 한다. 이 메서드가 유효하려면 포인터가
활성 버튼 상태에 있어야
MUST 하며, 그렇지 않으면 조용히 실패한다. 제공된 메서드의 인수가
어떤 활성 포인터와도 일치하지 않으면, "NotFoundError" DOMException을
throw한다.
releasePointerCapture()인수 pointerId로
식별되는 포인터에 대해, 이 메서드가 호출된 요소에서 포인터 캡처를 해제한다.
해당 포인터의 이후 이벤트는 이벤트 대상을 결정하기 위해 일반적인 히트 테스트 메커니즘
(이 사양의 범위 밖)을 따른다. 제공된 메서드의 인수가 어떤 활성 포인터와도 일치하지 않으면, "NotFoundError" DOMException을
throw한다.
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 |
| 적용 대상: | 다음을 제외한 모든 요소: 비치환 인라인 요소, 표 행, 행 그룹, 표 열, 및 열 그룹 |
| 상속됨: | 아니요 |
| 백분율: | N/A |
| 미디어: | visual |
| 계산값: | 지정값과 같음 |
| 표준 순서: | 문법에 따름 |
| 애니메이션 유형: | 애니메이션 불가 |
touch-action CSS 속성은 직접
조작 상호작용(속성 이름에도 불구하고 터치에만 한정되지 않음)이 사용자 에이전트의 팬 및 줌
동작을 트리거할 수 MAY 있는지를 결정한다. touch-action 값에 관한 절을 참조하라.
팬 또는 줌을 시작하기 직전, 다음 조건이 모두 참이면 사용자 에이전트는 포인터 이벤트 스트림을 억제해야 MUST 한다:
pointerdown 이벤트가 전송되었으며,pointerdown 이후의
pointerup 또는 pointercancel 이벤트가 아직
해당 포인터에 대해 전송되지 않았다.
touch-action은 임베디드 브라우징 컨텍스트로 적용/캐스케이드되지 않는다.
예를 들어, <iframe>에 touch-action을 적용하더라도
<iframe> 자체 내부에서의 팬 및 줌을 위한 직접 조작 상호작용의 동작에는
아무런 영향을 주지 않는다.
사용자가 직접 조작 포인터(예: 터치스크린의 터치 또는 스타일러스)를 사용하여 요소와 상호작용할 때,
그 입력의 효과는 touch-action 속성의 값과 요소 및 그 조상의 기본 직접 조작 동작에 의해
다음과 같이 결정된다:
touch-action을 준수한다. CSS 변환이 적용된 경우,
요소의 좌표 공간은 여기서의 준수 여부에 영향을 주는 방식으로 화면 좌표와 다를 수 있음을 유의하라.
예를 들어, 화면을 기준으로 90도 회전된 요소의 X축은 화면 좌표의 Y축과 평행하게 된다.touch-action 속성을 준수하면 지원된다.
document 요소([HTML]에 정의됨) 사이의 각 요소의
touch-action 속성을 준수하면 지원된다.
touch-action 값에 대한 모든 변경은
해당 동작이 지속되는 동안 무시된다. 예를 들어, pointerdown 핸들러 스크립트의 일부로
어떤 요소의 touch-action 값을 auto에서 none으로
프로그래밍 방식으로 변경하더라도, 그 포인터가 활성 상태인 동안 해당 입력에 대한 팬 또는 줌 동작을
사용자 에이전트가 중단하거나 억제하지 않는다.
pan-*의 다양한 touch-action 값의 경우,
제스처 시작 시 사용자 에이전트가 제스처를 직접 처리할지 여부를 결정하고 나면,
같은 제스처의 이후 방향 변경은 해당 포인터가 활성 상태인 동안 사용자 에이전트가 무시하는 것이 좋다
SHOULD. 예를 들어, 어떤 요소가
touch-action: pan-y(세로 팬만 사용자 에이전트가 처리함을 의미)로 설정되어 있고,
터치 제스처가 가로 방향으로 시작한 경우, 사용자가 손가락을 화면에 계속 닿은 상태로 제스처 방향을
세로로 바꾸더라도 세로 팬은 발생하지 않는 것이 좋다.
touch-action 값을 처리하거나 연관시키는 방법은
이 사양의 범위 밖이다.touch-action 속성은 뷰포트 팬 및 줌과 관련된 직접 조작 동작을 다룬다.
텍스트 선택/강조 또는 링크와 폼 컨트롤 활성화와 같은 추가 사용자 에이전트 동작은
이 CSS 속성의 영향을 받아서는 안 된다 MUST NOT.
auto나 none 값에 대한 동작을
트리거하기 위한 상호작용 또는 제스처의 정의는 이 사양의 범위 밖이다.pan-x 또는 pan-y), 팬 도중 축을 변경할 수 없다.touch-action 값은 [COMPAT]에 정의되어 있다.방향별 pan 값은 일부 오버스크롤 동작을 사용자 정의하는 데 유용하다.
예를 들어, 단순한 pull-to-refresh 효과를 구현하려면 스크롤 위치가 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"> 컨트롤과 유사한 것) 같은 시나리오에서 유용하다.
포인터 캡처는 슬라이더 thumb 요소에 설정할 수 있으며, 이를 통해 포인터가 thumb에서 벗어나더라도
사용자가 컨트롤을 앞뒤로 슬라이드할 수 있다.
pointerdown 이후, 포인터가
thumb에서 벗어나더라도
사용자가 thumb를 슬라이드할 수 있도록 포인터 캡처를 사용할 수 있다.
포인터 캡처는 element.setPointerCapture(pointerId) 메서드를 호출하여
Element 유형의
element에 설정된다.
이 메서드가 호출되면, 사용자 에이전트는 다음
단계를 실행해야
MUST 한다:
pointerId가 어떤
활성 포인터와도 일치하지 않으면, "NotFoundError" DOMException을
throw한다.
pointerId로 지정된
활성 포인터로 둔다.
InvalidStateError" DOMException을
throw한다.
pointerLockElement)가
있으면,
"InvalidStateError" DOMException을
throw한다.
pointerId에 대해, 보류 중인 포인터 캡처 대상 재정의를 이 메서드가 호출된
Element로 설정한다.
pointerdown 리스너에서 해제하려는 실패한 시도에도
적용된다.포인터 캡처는 element.releasePointerCapture(pointerId) 메서드를 호출하여
요소에서 명시적으로 해제된다. 이 메서드가 호출되면, 사용자 에이전트는 다음 단계를
실행해야 MUST 한다:
pointerId가 어떤
활성 포인터와도 일치하지 않고,
이 단계들이 포인터 캡처의 암시적
해제의 결과로
호출되는 것이 아니면, "NotFoundError" DOMException을
throw한다.
pointerId를 가진
Element에 대해
hasPointerCapture가 false이면,
이 단계를 종료한다.
pointerId에 대해, 설정되어 있다면
보류 중인 포인터 캡처 대상
재정의를 지운다.
팬 및 줌을 위한 직접 조작 상호작용을 구현하는 입력
(예: 터치스크린의 터치 또는 스타일러스)은, 모든 pointerdown 리스너가 호출되기 직전에 대상
요소에서
setPointerCapture가 호출된 것과
정확히 같이 동작하는 것이 좋다 SHOULD. 이것이 발생했는지 확인하기 위해
hasPointerCapture API를 사용할 수 있다
(예를 들어 pointerdown 리스너 안에서). 다음 포인터 이벤트가
발생하기 전에 해당 포인터에 대해 releasePointerCapture가 호출되지
않으면, 캡처가 활성 상태임을 나타내는 gotpointercapture 이벤트가
(일반적으로)
대상에 디스패치된다.
pointerup 또는 pointercancel 이벤트를 발생시킨 직후,
사용자 에이전트는
방금 디스패치된 pointerup 또는 pointercancel 이벤트의
pointerId에 대해
보류 중인 포인터 캡처 대상
재정의를 지워야 MUST 하며,
그 다음 필요한 경우 lostpointercapture를
발생시키기 위해
보류 중인 포인터 캡처 처리 단계를 실행한다.
보류 중인 포인터 캡처 처리 단계를 실행한 뒤,
포인터가 호버를 지원하면, 사용자 에이전트는
캡처가 없는 상태에서
포인터의 현재 위치를 반영하는 데 필요한 대응하는 경계 이벤트도 보내야
MUST 한다.
포인터 캡처 대상 재정의가 더 이상 연결되어 있지 않으면 [DOM], 포인터 캡처 대상 재정의는 document로 설정되는 것이 좋다 SHOULD.
보류 중인 포인터 캡처 대상 재정의가 더 이상 연결되어 있지 않으면 [DOM], 보류 중인 포인터 캡처 대상 재정의 노드는 지워지는 것이 좋다 SHOULD.
lostpointercapture 이벤트가
document에서 발생한다.
포인터 잠금 [PointerLock]이 요소에 성공적으로 적용되면,
어떤 요소가 캡처되도록 설정되어 있거나 캡처되도록 보류 중인 경우 사용자 에이전트는
releasePointerCapture 메서드가
호출된 것처럼 단계를 실행해야 MUST 한다.
성능상의 이유로, 사용자 에이전트는 포인터의 측정 가능한 속성
(예: 좌표, 압력, 접선 압력, 기울기, twist 또는 접촉 기하 구조)이 업데이트될 때마다
pointermove
이벤트를 보내지 않도록 선택할 수 있다. 대신, 여러 변경을 하나의
pointermove 또는 pointerrawupdate 이벤트로
병합(결합/통합)할 수 있다. 이 접근 방식은 사용자
에이전트가 수행해야
MUST 하는 이벤트 처리량을 줄이는 데 도움이 되지만,
특히 빠르고 큰 움직임에서 포인터 위치를 추적할 때 자연스럽게 세분성과 충실도가 낮아진다.
getCoalescedEvents 메서드를
사용하면 애플리케이션이 원시의 병합되지 않은 위치 변경에 접근할 수 있다. 이를 통해 포인터 이동
데이터를 더 정밀하게 처리할 수 있다. 예를 들어 드로잉 애플리케이션의 경우, 병합되지 않은 이벤트를
사용하여 포인터의 실제 움직임에 더 가깝게 맞는 더 부드러운 곡선을 그릴 수 있다.
pointermove 이벤트의
병합된 좌표만 사용하면(회색 점), 곡선은 눈에 띄게 각지고 들쭉날쭉하다. getCoalescedEvents()가
제공하는 더 세분화된 점(빨간 원)을 사용해 같은 선을 그리면 포인터 이동에 대한 더 부드러운
근사가 된다.PointerEvent는 연관된 병합된
이벤트 목록(0개 이상의 PointerEvent의 목록)을 가진다.
신뢰된 pointermove 및
pointerrawupdate 이벤트의 경우, 목록은
이 이벤트로 병합된 모든 PointerEvent의 시퀀스이다.
"부모"인 신뢰된 pointermove 및
pointerrawupdate 이벤트는 이러한 병합된 이벤트의
누적을 나타내지만, 추가 처리(예: 디스플레이 새로 고침 속도에 맞추기)를 가질 수 있다.
그 결과, 이러한 이벤트의 병합된 이벤트 목록은 항상 적어도 하나의 이벤트를 포함한다.
다른 모든 신뢰된 이벤트 유형의 경우, 이는 빈 목록이다. 신뢰되지 않은 이벤트는 그
병합된 이벤트 목록이 생성자에 전달된 값으로
초기화된다.
isTrusted 비트를
false로 설정하지만, 병합된
이벤트 목록의 같은 비트들은 원래의 true 값에서 변경되지 않은 채로 유지된다.
신뢰된 이벤트의 병합된 이벤트 목록에 있는 이벤트는 다음을 가진다:
timeStamp 값
[DOM] — 모든 병합된 이벤트는
getPredictedEvents 메서드가
호출된 디스패치된 포인터 이벤트의 timeStamp보다
작거나 같은 timeStamp를 가진다.
병합된 이벤트 목록은 timeStamp 기준으로
시간순으로 정렬되어야 MUST 하므로, 첫 번째 이벤트가 가장 작은
timeStamp를 가진다.
pointerId,
pointerType,
및 isPrimary.
<style>
/* 내장 사용자 에이전트 직접 조작 동작(예: 팬 또는 줌)을 비활성화하여
canvas 요소의 모든 이벤트가 대신 애플리케이션에 전달되도록 한다. */
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>
디스패치되는 이러한 모든 이벤트의 순서는 원래 이벤트의 실제 순서와 일치해야
MUST 한다.
예를 들어 pointerdown 이벤트가
병합된 pointermove 이벤트의 디스패치를 유발하는 경우,
사용자 에이전트는 먼저 해당
pointerId의 모든
병합된 이벤트를 가진 하나의 pointermove 이벤트를 디스패치한 뒤,
pointerdown 이벤트를 디스패치해야
MUST 한다.
다음은 증가하는 timeStamp 값과 함께
발생하는 실제 이벤트와 사용자 에이전트가 디스패치하는 이벤트의 예이다:
| 실제 이벤트 | 디스패치된 이벤트 |
|---|---|
포인터 (pointerId=2)
좌표 변경 |
pointerrawupdate (pointerId=2),
병합된 이벤트 하나 포함 |
포인터 (pointerId=1)
좌표 변경 |
pointerrawupdate (pointerId=1),
병합된 이벤트 하나 포함 |
포인터 (pointerId=2)
좌표 변경 |
pointerrawupdate (pointerId=2),
병합된 이벤트 하나 포함 |
포인터 (pointerId=2)
좌표 변경 |
pointerrawupdate (pointerId=2),
병합된 이벤트 하나 포함 |
포인터 (pointerId=1)
좌표 변경 |
pointerrawupdate (pointerId=1),
병합된 이벤트 하나 포함 |
포인터 (pointerId=2)
좌표 변경 |
pointerrawupdate (pointerId=2),
병합된 이벤트 하나 포함 |
포인터 (pointerId=1) 버튼
누름 |
pointermove
(pointerId=1),
병합된 이벤트 두 개 포함pointermove
(pointerId=2),
병합된 이벤트 네 개 포함pointerdown
(pointerId=1),
병합된 이벤트 0개 포함 |
포인터 (pointerId=2)
좌표 변경 |
pointerrawupdate (pointerId=2),
병합된 이벤트 하나 포함 |
포인터 (pointerId=2)
좌표 변경 |
pointerrawupdate (pointerId=2),
병합된 이벤트 하나 포함 |
포인터 (pointerId=1) 버튼
해제 |
pointermove
(pointerId=2),
병합된 이벤트 두 개 포함pointerup (pointerId=1),
병합된 이벤트 0개 포함 |
일부 사용자 에이전트에는 일련의 확인된 포인터 이동 이후, 현재 제스처의 선행 이벤트와
이동의 속도/궤적에 기반하여 미래 포인터 이동의 위치가 어디일지 예측할 수 있는 내장 알고리즘이 있다.
애플리케이션은 getPredictedEvents 메서드를
사용하여 이 정보를 활용할 수 있으며, 체감 지연 시간을 줄이기 위해 예측된 위치까지 추측적으로
"앞서 그린" 뒤 실제 점이 수신되면 이러한 예측 점을 폐기할 수 있다.
pointermove 이벤트의 병합된 좌표를 사용하며,
사용자 에이전트의 예측된 미래 점(회색 원)을 보여준다.PointerEvent는 연관된 예측된
이벤트 목록(0개 이상의 PointerEvent의 목록)을 가진다.
신뢰된 pointermove 이벤트의 경우, 이는 사용자 에이전트가
미래에 해당 이벤트 뒤를 따를 것으로 예측하는 PointerEvent들의 시퀀스이다.
다른 모든 신뢰된 이벤트 유형의 경우, 이는 빈 목록이다.
신뢰되지 않은 이벤트는 그 예측된 이벤트 목록이
생성자에 전달된 값으로 초기화된다.
pointerrawupdate 이벤트는 비어 있지 않은 병합된 이벤트
목록을 가질 수 있지만,
성능상의 이유로 그 예측된 이벤트 목록은 일반적으로 빈 목록이 된다.
isTrusted 비트를
false로 설정하지만, 예측된
이벤트 목록의 같은 비트들은 원래의 true 값에서 변경되지 않은 채로 유지된다.
목록 안의 이벤트 수와 현재 타임스탬프로부터 얼마나 떨어져 있는지는 사용자 에이전트와 그 사용자 에이전트가 사용하는 예측 알고리즘에 의해 결정된다.
신뢰된 이벤트의 예측된 이벤트 목록에 있는 이벤트는 다음을 가진다:
timeStamp 값
[DOM] — 모든 예측된 이벤트는
getPredictedEvents 메서드가
호출된 디스패치된 포인터 이벤트의 timeStamp보다
크거나 같은 timeStamp를 가진다.
예측된 이벤트 목록은 timeStamp 기준으로
시간순으로 정렬되어야 MUST 하므로, 첫 번째 이벤트가 가장 작은
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가 생성될 때, 사용자 에이전트는
병합된 이벤트 목록 및 예측된 이벤트 목록 안의
각 이벤트에 대해 다음 단계를
실행하는 것이 좋다 SHOULD:
pointerId,
pointerType,
isPrimary 및 isTrusted를
"부모" 포인터 이벤트의 각각의 속성과 일치하도록 설정한다.
cancelable 및 bubbles를 false로
설정한다(이러한 이벤트는 결코 단독으로 디스패치되지 않기 때문이다).PointerEvent 값으로 초기화한다.
신뢰된 PointerEvent의 target이 변경될 때,
사용자 에이전트는 병합된 이벤트 목록 및 예측된 이벤트 목록 안의
각 이벤트에 대해 다음을
실행하는 것이 좋다 SHOULD:
오늘날 존재하는 웹 콘텐츠의 압도적 다수는 Mouse Events만을 대상으로 작성되어 있다. 다음은 사용자 에이전트가 이러한 콘텐츠와의 호환성을 위해 일반 포인터 입력을 마우스 이벤트로 매핑할 수 MAY 있는 방법에 대한 알고리즘을 설명한다.
마우스 이벤트와의 호환성 매핑은 이 사양의 OPTIONAL 기능이다. 사용자 에이전트는 기존 레거시 콘텐츠와의 최상의 호환성을 위해 이 기능을 지원하는 것이 권장된다.
높은 수준에서, 호환성 마우스 이벤트는 각각의 포인터 이벤트와 "끼워 넣어져" 발생하도록 의도되어 있다. 그러나 이 특정 순서는 필수는 아니며, 호환성 마우스 이벤트를 구현하는 사용자 에이전트는 상대적 순서가 일관되는 한 마우스 이벤트의 디스패치를 지연하거나 그룹화하기로 결정할 수 MAY 있다.
특히 터치스크린 입력의 경우, 사용자 에이전트는 제스처 인식을 위해 추가 휴리스틱을 적용할 수
MAY 있다(저자가 을
통해 명시적으로
억제하지 않는 한). touch-actionpointerdown 이벤트와 pointerup 이벤트 사이의 이벤트 시퀀스 동안,
제스처 인식은 제스처를 감지하거나 무시하기 위해 pointerup 이벤트까지 기다려야 할 수 있다.
그 결과, 사용자 에이전트가 상호작용이 특정 제스처로 의도되지 않았다고 판단한 경우 전체 시퀀스에
대한 호환성 마우스 이벤트는 마지막 pointerup 이벤트 이후에
함께 디스패치될 수 있다. 사용자 에이전트 제스처 인식의 이러한 세부 사항은 이 사양에서
정의하지 않으며, 구현마다 다를 수 있다.
호환성 마우스 이벤트 지원 여부와 관계없이, 사용자 에이전트는 click,
auxclick 및 contextmenu 이벤트를 항상 지원해야 MUST 한다. 이러한 이벤트는
PointerEvent 유형이므로
호환성 마우스 이벤트가 아니기 때문이다.
포인터 이벤트 중 preventDefault를 호출하는 것은 click,
auxclick 또는 contextmenu가 발생하는지 여부에 영향을 주어서는 안 된다
MUST NOT.
이러한 고수준 이벤트 중 일부(예: contextmenu, focus, blur)와 포인터
이벤트의 상대적 순서는 정의되어 있지 않으며 사용자 에이전트마다 다르다. 예를 들어, 어떤 사용자
에이전트에서는 contextmenu가 종종 pointerup 뒤에 오지만, 다른 사용자 에이전트에서는
종종 pointerup 또는 pointercancel보다 앞서며, 어떤 상황에서는
대응하는 포인터 이벤트 없이 발생할 수 있다(예: 키보드 상호작용의 결과로).
또한, 사용자 에이전트는 click, auxclick 또는
contextmenu 이벤트를 발생시킬지 여부를 결정하기 위해 자체 휴리스틱을 적용할 수 있다.
일부 사용자 에이전트는 같은 유형의 다른(기본이 아닌) 포인터가 있거나 다른 유형의 다른 기본
포인터가 있는 경우 이러한 이벤트를 발생시키지 않기로 선택할 수 있다. 사용자 에이전트는 특정 동작이
"깔끔한" 탭, 클릭 또는 길게 누르기가 아니라고 판단할 수 있으며(예를 들어 터치스크린 위의 손가락
상호작용에서 손가락이 화면에 닿아 있는 동안 너무 많이 움직인 경우), click,
auxclick 또는 contextmenu 이벤트를 발생시키지 않기로 결정할 수 있다.
사용자 에이전트 동작의 이러한 측면은 이 사양에서 정의하지 않으며, 구현마다 다를 수 있다.
달리 명시되지 않는 한, 매핑된 모든 마우스 이벤트의 대상은 그 대상이 더 이상 자신의
ownerDocument 트리에 참여하지 않는 경우를 제외하고는 각각의 포인터 이벤트와 같은 대상인
것이 좋다 SHOULD. 이 경우, 마우스 이벤트는 원래 대상이 트리에서 제거된
시점에 그 원래 대상의 가장 가까운 조상 노드 중 여전히 자신의 ownerDocument 트리에
참여하는 노드에서 발생하는 것이 좋으며, 이는 마우스 이벤트에 대해 (새 대상 노드에 기반한) 새 이벤트
경로가 만들어짐을 의미한다.
저자는 pointerdown 이벤트를 취소함으로써 특정 호환성
마우스 이벤트의 생성을 방지할 수 있다.
마우스 이벤트는 포인터가 내려가 있는 동안에만 방지될 수 있다. 호버 중인 포인터(예: 버튼이 눌리지 않은 마우스)는 그 마우스 이벤트를 방지할 수 없다.
mouseover, mouseout, mouseenter, 및 mouseleave
이벤트는 결코 방지되지 않는다(포인터가 내려가 있더라도).
포인터 이벤트 EventListener가
passive로
설정된 경우, 호환성 마우스 이벤트는 방지될 수 없다
[DOM].
기본 포인터만 호환성 마우스 이벤트를 생성할 수 있지만,
여러 기본 포인터가 동시에 활성화될 수 있으며, 각각은 자체
호환성 마우스 이벤트를 생성한다. MouseEvents에 의존하는 스크립트와의 호환성을 위해, 마우스 전환
이벤트(mouseover, mouseout, mouseenter 및
mouseleave)는 단일 레거시 마우스 입력의 이동을 시뮬레이트하는 것이 좋다
SHOULD. 이는 모든 이벤트 대상에 대한 진입/이탈 상태가
[UIEVENTS]에 따라 유효하다는 것을 의미한다. 사용자 에이전트는
문서에서 레거시 마우스 포인터의 유효 위치를 다음과 같이 유지함으로써 이를
보장하는 것이 좋다 SHOULD.
pointerdown, pointerup 또는 pointermove 이벤트, 또는 window에서의
pointerleave 이벤트를 발생시키기 직전에,
사용자 에이전트는 다음 단계를 실행하는 것이 좋다 SHOULD:
pointerdown, pointerup 또는 pointermove 이벤트의 대상으로 둔다. pointerleave 이벤트의 경우,
T를 설정 해제한다.
mouseover, mouseout, mouseenter 및
mouseleave 이벤트를 디스패치한다. 현재 레거시 마우스 포인터의 유효 위치
또는 T 중 하나의 설정 해제 값을 창 밖의 마우스 위치로 간주한다.
레거시
마우스 포인터의 유효 위치는 포인터 전환 이벤트(pointerover,
pointerout, pointerenter
및 pointerleave)에서 대응하는 레거시 마우스 전환 이벤트
(mouseover,
mouseout, mouseenter 및 mouseleave)로 항상 직접
매핑할 수는 없다는 사실을 모델링한다. 다음 애니메이션은 단일 레거시 마우스 입력을 사용하여
두 기본 포인터를 조정할 수 있도록, 사용자 에이전트가 포인터 전환 이벤트보다 더 많은 레거시
마우스 전환 이벤트를 디스패치해야 하는 경우를 보여준다.
이 애니메이션에서 마우스 클릭과 터치 탭 사이의 시간 구간에 주목하라. Button 1은
pointerout 이벤트를 받지 않는다(이 기간 동안 "실제" 마우스 포인터가 버튼
사각형을 떠나지 않았기 때문). 그러나 터치 탭에서 레거시 마우스 포인터의
유효 위치가 Button 2로 이동할 때 Button 1은 mouseout 이벤트를 받는다.
마찬가지로, 터치 탭과 마우스가 Button 1을 떠나기 직전 사이의 시간 구간에서 Button 1은
같은 이유로 pointerover 이벤트를 받지 않지만, 레거시 마우스 포인터의
유효 위치가 Button 1 안으로 다시 이동할 때 Button 1은 mouseover 이벤트를
받는다.
사용자 에이전트가 호버를 지원하는 장치에 대해 포인터 이벤트를 디스패치하려 할 때마다, 다음 단계를 실행하는 것이 좋다 SHOULD:
isPrimary 속성이 false이면, 포인터 이벤트를
디스패치하고 이 단계를 종료한다.pointerdown, pointerup 또는 pointermove 이벤트이거나,
window에서의 pointerleave 이벤트이면,
레거시 마우스
포인터의 유효 위치 추적에 설명된 대로 호환성 마우스 전환 이벤트를 디스패치한다.
pointerdown이고 이벤트의 canceled flag가 설정되어
있으면,
이 pointerType에 대한 PREVENT MOUSE EVENT 플래그를 설정한다.
pointerType에 대해 PREVENT MOUSE EVENT 플래그가 설정되어
있지 않고, 디스패치된 포인터 이벤트가 다음과 같은 경우:
pointerdown이면,
mousedown 이벤트를 발생시킨다.
pointermove이면,
mousemove 이벤트를 발생시킨다.
pointerup이면,
mouseup 이벤트를 발생시킨다.
pointercancel이면,
window에서 mouseup 이벤트를 발생시킨다.
pointerup 또는 pointercancel이면, 이
pointerType에 대한 PREVENT MOUSE EVENT 플래그를 지운다.
대부분의 터치스크린과 같은 일부 장치는 활성 상태가 아닐 때 좌표(또는 좌표 집합)를 호버하는 것을 지원하지 않는다. 마우스 이벤트를 대상으로 작성된 많은 기존 콘텐츠는 마우스가 이벤트를 생성한다고 가정하므로 일반적으로 특정 성질이 참이라고 가정한다:
mousemove 이벤트를 생성할 가능성이 높다.
이는 사용자 에이전트가 이러한 유형의 입력 장치에 대해 다른 매핑을 제공해야 함을 요구한다. 사용자 에이전트가 호버를 지원하지 않는 장치에 대해 포인터 이벤트를 디스패치하려 할 때마다, 다음 단계를 실행하는 것이 좋다 SHOULD:
isPrimary 속성이 false이면, 포인터 이벤트를
디스패치하고 이 단계를 종료한다.pointerover이고, 이 포인터에 대해
pointerdown 이벤트가 아직 디스패치되지
않았다면, (레거시 마우스 전용 코드와의 호환성을 위해) mousemove 이벤트를 발생시킨다.
pointerdown, pointerup 또는 pointermove 이벤트이거나,
window에서의 pointerleave 이벤트이면,
레거시 마우스
포인터의 유효 위치 추적에 설명된 대로 호환성 마우스 전환 이벤트를 디스패치한다.
pointerdown이고 이벤트의 canceled flag가 설정되어
있으면,
이 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]에 개요로 제시된 fallback mouse events를 둘 다 생성해서는 안 된다 MUST NOT.
호버를 지원하지 않는 기본 포인터(예:
터치스크린의 한 손가락)를 사용한 요소의 활성화(click)는 일반적으로 다음 이벤트 시퀀스를 생성한다:
mousemovepointeroverpointerentermouseovermouseenterpointerdownmousedownpointermove 및
mousemove 이벤트
pointerupmouseuppointeroutpointerleavemouseoutmouseleaveclick그러나 이 상호작용 중 pointerdown 이벤트의 canceled flag가
설정되면 이벤트 시퀀스는 다음과 같다:
mousemovepointeroverpointerentermouseovermouseenterpointerdownpointermove 이벤트
pointeruppointeroutpointerleavemouseoutmouseleaveclick이 부록은 Pointer Events 구현에 대한 보안 및 개인정보 보호 고려사항을 논의한다. 논의는 이 사양에 정의된 이벤트 모델, API 및 이벤트의 구현에서 직접 발생하는 보안 및 개인정보 보호 문제로 제한된다.
이 사양에 정의된 많은 이벤트 유형은 사용자 동작에 응답하여 디스패치된다. 이는 악의적인 이벤트 리스너가 사용자가 일반적으로 기밀이라고 생각할 정보, 예를 들어 페이지와 상호작용하는 동안 사용자의 마우스/스타일러스/손가락의 정확한 경로/움직임에 접근할 수 있게 한다.
포인터 이벤트는 (사용자 장치에서 지원되는 경우) 펜 입력이 유지되는 각도나 기울기, 접촉면의 기하 구조, 스타일러스 또는 터치스크린에 가해지는 압력과 같은 추가 정보를 포함한다. 각도, 기울기, 기하 구조 및 압력에 대한 정보는 사용자 장치의 센서와 직접 관련되어 있으며, 이는 이 사양이 origin에 이러한 센서에 대한 접근을 허용함을 의미한다.
이 센서 데이터뿐 아니라 사용된 입력 메커니즘(마우스, 터치, 펜)의 유형을 결정할 수 있는 능력은 사용자, 또는 사용자의 장치와 환경의 특성을 추론하는 데 사용될 수 있다. 이러한 추론된 특성과 모든 장치/환경 정보는 그 자체로 민감할 수 있다. 예를 들어, 악의적인 사이트가 사용자가 보조 기술을 사용하고 있는지를 추가로 추론할 수 있게 할 수 있다. 이 정보는 또한 사용자 프로필을 만들거나 특정 사용자를 "fingerprint"하고 추적하려는 목적으로 잠재적으로 사용될 수 있다.
완화책으로, 사용자 에이전트는 사용자가 특정 센서 데이터(예: 각도, 기울기, 압력)에 대한 접근을 비활성화할 수 있는 기능을 포함하거나, 사용자의 명시적 opt-in 이후에만 이를 사용할 수 있도록 하는 것을 고려할 수 있다.
이 사양은 저자가 "예측된 이벤트"에 접근할 수 있는 방법을 정의한다. 사양 자체는 사용자 에이전트가 예측에 사용해야 하는 알고리즘을 정의하지 않는다. 사양 저자들은 알고리즘이 사용자가 수행 중인 현재 제스처와 관련된 선행 포인터 이벤트에만 의존할 것을 예상한다. 예측 알고리즘의 특정 구현이 사용자의 여러 사이트에 걸친 전체 상호작용 기록과 같은 추가 데이터에 의존하지 않도록 보장하는 것은 사용자 에이전트의 책임이다. 그러한 데이터는 사용자에 대한 민감한 정보를 드러내거나 사용자를 "fingerprint"하고 추적하는 데 사용될 수 있다.
이러한 고려사항 외에도, 작업 그룹은 이 사양이 다음과 같다고 믿는다:
이 절은 비규범적이다.
buttons 속성에 대해 0이 아닌 값을 가지는 상태. 마우스의 경우, 이는 장치의
적어도 하나의 버튼이 눌려 있을 때이다. 터치의 경우, 이는 디지타이저와 물리적 접촉이 있을 때이다.
펜의 경우, 이는 펜이 디지타이저와 물리적으로 접촉하고 있거나, 호버 중에 적어도 하나의 버튼이 눌려
있을 때이다.pointerId로 식별됨)가
문서 안에서 추가 이벤트를 생성할 수 있다면, 그 포인터는 여전히 활성 상태로 간주된다. 예:
WheelEvent 인터페이스를 지원하는 입력 장치
(예: 마우스 휠 또는 터치패드)의 물리적 움직임에 응답하여 사용자 에이전트가 페이지를 스크롤하거나
줌할 것으로 예상되는 스크롤 양(픽셀, 줄 또는 페이지 단위). delta의 값(예: deltaX, deltaY, 또는 deltaZ 속성)은 현재
deltaMode 속성의 문맥에서 해석되어야 한다.
휠(또는 다른 장치)의 물리적 움직임과 delta가 양수인지 음수인지의
관계는 환경 및 장치에 따라 달라진다. 그러나 사용자 에이전트가 기본 동작으로 스크롤한다면,
delta의 부호는
양의 X, Y, Z축이 각각 document의 가장
오른쪽 가장자리, 가장 아래쪽 가장자리, 그리고 가장 먼 깊이(사용자로부터 멀어지는 방향)를 향하는
오른손 좌표계에 의해 주어진다.
측정 가능한 속성은 실수 또는 큰 도메인의 정수로 표현되는 연속적인 포인터 센서 데이터와 관련된
값을 나타낸다. 포인터 이벤트의 경우, width, height,
pressure,
tangentialPressure, tiltX, tiltY, twist,
altitudeAngle, azimuthAngle, 그리고 [UIEVENTS] Mouse
Event 모델 속성
screenX, screenY, clientX, clientY는
측정 가능한 속성이다.
반대로 pointerId, pointerType,
isPrimary, 그리고
[UIEVENTS] Mouse Event 모델 속성 button,
buttons, ctrlKey,
shiftKey, altKey, 및 metaKey는 센서 데이터와 관련되지
않으므로 측정 가능한 속성으로 간주되지 않는다.
WheelEvent 인터페이스를 사용하는 입력 장치에서
점진적 변화의 표시. 일부 장치에서는 이것이 휠의 문자 그대로의 회전일 수 MAY 있으며, 다른 장치에서는 평평한 표면을 따라 움직이는
것이거나 특정
버튼에 대한 압력일 수 MAY 있다.히트 테스트기능이 대상을 결정하는 데 사용된다. 히트 테스트 및 쌓임 순서에 관한 구체적인 세부 사항은 호스트 언어를 참조하라.
이 절은 규범적이다. 다음 기능은 폐기되었으며, 레거시 소프트웨어와의 호환성을 요구하는 사용자 에이전트에 의해서만 구현되어야 한다. [UIEvents]의 레거시 이벤트 초기화자도 참조하라.
WebIDLpartial interface MouseEvent {
};
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] 사양과 비교하여, 이 사양의 발행물 사이에 이루어진 실질적이고 주요한 편집 변경에 대한 정보 제공용 요약이다. 이 사양의 Editor's Drafts 전체 개정 이력을 참조하라.
WebIDL[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 MouseEventInit : EventModifierInit {
long screenX = 0;
long screenY = 0;
long clientX = 0;
long clientY = 0;
short button = 0;
unsigned short buttons = 0;
EventTarget? relatedTarget = null;
};
dictionary 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();
};
[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;
};
dictionary WheelEventInit : MouseEventInit {
double deltaX = 0.0;
double deltaY = 0.0;
double deltaZ = 0.0;
unsigned long deltaMode = 0;
boolean momentum = false;
};
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;
};
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:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in: