Copyright © 2026 World Wide Web Consortium. W3C® liability, trademark and permissive document license rules apply.
Pointer Events 명세는 마우스, 터치스크린, 펜/스타일러스 등 다양한 장치로부터 입력을 처리하기 위한 통합 하드웨어 비의존 프레임워크를 정의합니다. pointerdown, pointermove, pointerup과 같은 단일 이벤트 집합을 제공함으로써, 개발자는 각 장치별로 별도의 로직을 작성하지 않고도 다양한 입력 방식을 지원할 수 있습니다.
이 명세는 또한 마우스 및 휠 이벤트와 기타 포인터 장치 유형에 대해 마우스 이벤트를 발생시키는 매핑도 정의합니다.
이 섹션은 본 문서가 출판될 당시의 상태를 설명합니다. 최신 W3C 발행물 목록과 이 기술 보고서의 최신 개정본은 W3C 표준 및 초안 인덱스에서 확인할 수 있습니다.
본 명세는 [PointerEvents3] 명세의 업데이트 버전입니다. 또한, 기존 [UIEVENTS] 명세에 있던 마우스 및 휠 이벤트를 포함합니다.
이 개정판에는 다음과 같은 새로운 기능이 포함되어 있습니다:
persistentDeviceId: 여러 상호작용에 걸쳐 입력 장치의 안정적인 식별자를 제공합니다.touch-action 값: pan-left,
pan-right, pan-up, pan-down
본 문서는 Pointer Events Working Group에 의해 권고 트랙을 사용하여 작업 초안으로 발행되었습니다.
작업 초안으로서의 출판은 W3C 및 그 회원사의 승인 또는 동의를 의미하지 않습니다.
이 문서는 초안 상태이며, 언제든지 다른 문서로 대체, 수정, 폐기될 수 있습니다. 진행 중인 작업 외에는 이 문서를 인용하는 것은 적절하지 않습니다.
본 문서는 W3C 특허 정책에 따라 운영되는 그룹에 의해 작성되었습니다. W3C는 해당 그룹의 결과물과 관련하여 공개 특허 공개 목록 을 유지 관리합니다. 이 페이지에는 특허 공개 방법에 대한 안내도 포함되어 있습니다. 특정 특허에 Essential Claim(필수 청구)이 포함되어 있다고 인지한 개인은 W3C 특허 정책 제6조에 따라 이 정보를 공개해야 합니다.
이 문서는 2025년 8월 18일자 W3C 프로세스 문서의 적용을 받습니다.
이 섹션은 규범적이지 않습니다.
현재 대부분의 [HTML] 콘텐츠는 마우스 입력과 함께 사용되거나 이를 위해 설계됩니다. 입력을 커스텀 방식으로 처리하는 경우는 보통 [UIEVENTS] 마우스 이벤트에 맞춰 코드를 작성합니다. 하지만 최근의 컴퓨팅 장치는 터치스크린, 펜 입력 등 다양한 형태의 입력을 도입하고 있습니다. 이러한 입력 각각을 별도로 처리하기 위한 이벤트 타입들이 제안되었지만, 이 방식은 새로운 입력 타입을 지원할 때 불필요하게 로직의 중복과 이벤트 처리 오버헤드를 유발하곤 합니다. 그 결과, 하나의 장치만을 염두에 두고 작성된 콘텐츠에서는 호환성 문제가 발생하기도 합니다. 또한 기존 마우스 기반 콘텐츠와의 호환성을 위해 대부분의 user agent는 모든 입력 타입에 대해 마우스 이벤트를 발생시킵니다. 이로 인해 마우스 이벤트가 실제 마우스 장치에서 발생한 것인지, 아니면 호환성을 위해 다른 입력 타입에서 생성된 것인지 모호해집니다. 그 결과 두 장치 타입 모두를 동시에 처리하는 코드 작성이 어려워집니다.
여러 입력 타입에 맞춰 코드를 작성하는 비용을 줄이고 위에서 언급한 마우스 이벤트의 모호성 문제를 완화하기 위해, 이 명세는 포인터라는 보다 추상화된 입력 개념을 정의합니다. 포인터란 마우스 커서, 펜, 터치(멀티터치 포함), 그 외의 포인팅 입력 장치로 화면의 한 점(또는 여러 점)에 만든 접점을 의미합니다. 이 모델을 사용하면 사용자의 하드웨어가 무엇이든 상관없이 잘 동작하는 사이트와 애플리케이션을 더 쉽게 만들 수 있습니다. 장치별 처리 로직이 필요한 경우를 위해, 이 명세는 이벤트를 발생시킨 장치 유형을 조회할 수 있는 속성도 제공합니다. 주요 목표는, 교차 장치 포인터 입력을 간단히 처리할 수 있는 단일 이벤트 및 인터페이스 집합을 제공하되, 보다 향상된 경험을 위해 필요한 경우에만 장치별 처리를 허용하는 것입니다.
또 다른 핵심 목표는, 멀티스레드 user agent가 직접 조작 액션(예: 손가락이나 스타일러스로 터치스크린에서 팬 또는 줌)을, 자바스크립트 실행 차단 없이 처리할 수 있도록 지원하는 것입니다.
이 명세는 다양한 포인터 입력에 대한 통합 이벤트 모델을 정의하지만, 키보드 또는 유사 키보드 인터페이스(예: 스크린 리더나, 터치스크린만 있는 기기의 보조 기술 등)와 같은 다른 형태의 입력은 포함하지 않습니다. 이러한 인터페이스에 대해 user agent가 포인터 이벤트를 생성할 수는 있지만, 이 상황은 본 명세의 범위에 포함되지 않습니다.
최우선으로, 작성자들은 focus, blur 및
click 등 상위 레벨 이벤트에 반응하여 모든 입력 방식에 대해 동등한 기능을 제공하는 것이 권장됩니다.
하지만 포인터 이벤트 같은 저수준 이벤트를 사용할 때에는, 모든 입력 타입이 지원되도록 확보해야 합니다.
키보드 및 유사 키보드 인터페이스의 경우, 명시적인 키보드 이벤트 처리가 추가로 필요할 수 있습니다.
더 자세한 내용은 키보드 접근성
[WCAG22]을 참고하세요.
제네릭 포인터 입력을 처리하는 이벤트들은 마우스 이벤트들과 매우 유사합니다: pointerdown,
pointermove, pointerup, pointerover, pointerout 등입니다.
이를 통해 마우스 이벤트에서 포인터 이벤트로의 손쉬운 콘텐츠 마이그레이션이 가능합니다.
포인터 이벤트는 (클라이언트 좌표, 대상 엘리먼트, 버튼 상태 등) Mouse Event에 존재하는 모든 일반 속성뿐만 아니라,
압력, 접촉면, 기울기 등 다른 입력 방식 전용의 새로운 속성도 제공합니다.
작성자는 포인터 이벤트를 사용해 다양한 입력 방식 간에 로직을 공유할 수 있고,
최고의 경험을 위해 특정 입력 방식에만 맞춤 동작을 추가할 수도 있습니다.
포인터 이벤트는 다양한 입력 장치에서 발생하지만, 특정 장치별 이벤트(예: MouseEvent, TouchEvent)로부터 생성되어야 한다는 정의는 없습니다. 호환성을 위해 실제로 그렇게 하는 것이 권장될 수 있지만, 본 명세는 다른 장치별 이벤트의 지원을 필수로 요구하지 않습니다. 즉, user agent는 포인터 이벤트만 지원하고 다른 장치별 이벤트를 지원하지 않을 수 있습니다. 마우스 이벤트에만 맞춰 작성된 콘텐츠와의 호환성을 위해, 이 명세는 마우스 이외 장치의 포인터 입력을 기반으로 호환성 마우스 이벤트를 생성하는 방법에 대한 선택적 섹션도 제공합니다.
이 명세는 [TOUCH-EVENTS]에서 정의한 Touch Events와 Pointer Events 둘 다를 지원하는 user agent의 기대 동작에 대해 조언하지 않습니다. 이 두 명세 간의 관계에 대한 더 자세한 안내는 Touch Events Community Group을 참고하세요.
비규범적으로 표시된 섹션뿐만 아니라, 이 명세에 있는 모든 작성 가이드라인, 다이어그램, 예제, 참고 사항들은 모두 비규범입니다. 이 명세의 그 외 모든 내용은 규범적입니다.
이 문서의 MAY, MUST, MUST NOT, OPTIONAL, SHOULD 키워드는 BCP 14 [RFC2119] [RFC8174] 문서에서 설명한 대로, 그리고 오직 여기처럼 모두 대문자로 나타날 때에만 그 의미로 해석되어야 합니다.
이 섹션은 비규범적입니다.
아래는 이 명세의 일부 API가 작성자에 의해 어떻게 사용될 수 있는지를 보여주는 기본 예제들입니다. 더 구체적인 예제는 본 문서의 관련 섹션에서 제공합니다.
/* Pointer Events 또는 기존 터치/마우스 이벤트 바인딩 */
if (window.PointerEvent) {
// Pointer Events 지원 시, pointer 이벤트만 리스닝
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이 비어 있음(감지 불가)
또는 user agent별 커스텀 타입 */
}
}
<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 인터페이스는 마우스 이벤트와 관련된 구체적인
문맥 정보를 제공합니다.
중첩된 요소의 경우, 마우스 이벤트는 항상 가장 깊게 중첩된 요소를 대상으로 합니다.
대상 요소의 조상 요소들은 이벤트 버블링을 사용해, 그들의 자손 요소 내에서 발생하는 마우스 이벤트에 대한 알림을 받을 수 있습니다.
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은(는) 어떤 포인팅 장치 버튼이
상태를 변경했는지를 나타내기 위해 사용되어야 합니다.
button 속성의 값은 다음과 같아야 합니다:
0은(는) 장치의 주 버튼(일반적으로 왼쪽 버튼 또는 단일 버튼 장치의 유일한 버튼으로,
사용자 인터페이스 컨트롤을 활성화하거나 텍스트를 선택하는 데 사용됨) 또는 초기화되지 않은 값을
나타내야 합니다.
1은(는) 보조 버튼(일반적으로 마우스 휠과 함께 있는 가운데 버튼)을 나타내야 합니다.
2는(은) 2차 버튼(일반적으로 컨텍스트 메뉴 표시 등에 사용되는 오른쪽 버튼)을
나타내야 합니다.
3은(는) X1(뒤로) 버튼을 나타내야 합니다.
4는(은) X2(앞으로) 버튼을 나타내야 합니다.
일부 포인팅 장치는 더 많은 버튼 상태를 제공하거나 시뮬레이션하며,
이러한 버튼을 나타내기 위해 2보다 큰 값 또는 0보다 작은 값이
사용될 수도 있습니다.
button의 값은
마우스 버튼의 눌림/해제로 인해 발생하지 않은 이벤트에서는 업데이트되지 않습니다. 이러한 경우,
값 0을 왼쪽 버튼으로 해석하지 않도록 주의하고, 대신 기본값으로 취급해야 합니다.
이 속성의 초기화되지 않은 값은
MUST 0이어야 합니다.
buttons
모든 마우스 이벤트 동안, buttons는
현재 눌려 있는 마우스 버튼들의 조합을 비트마스크로 나타내기 위해 사용되어야 합니다.
이름은 비슷하지만, buttons 속성과 button 속성의 값은 매우 다릅니다.
button의
값은 mousedown / mouseup 이벤트 핸들러 동안 유효하다고 가정되는 반면,
buttons 속성은
신뢰할 수 있는 MouseEvent
객체가(디스패치되는 동안)
마우스 버튼의 상태를 반영합니다. 이는 "현재 활성 버튼 없음"(0) 상태를 표현할 수 있기 때문입니다.
buttons 속성의 값은 다음과 같아야 합니다:
0은(는) 현재 활성 버튼이 없음을 나타내야 합니다.
1은(는) 장치의 주 버튼(일반적으로 왼쪽 버튼 또는 단일 버튼 장치의 유일한 버튼으로,
사용자 인터페이스 컨트롤을 활성화하거나 텍스트를 선택하는 데 사용됨)을 나타내야 합니다.
2는(은) 존재한다면 2차 버튼(일반적으로 컨텍스트 메뉴 표시 등에 사용되는 오른쪽 버튼)을
나타내야 합니다.
4는(은) 보조 버튼(일반적으로 마우스 휠과 함께 있는 가운데 버튼)을 나타내야 합니다.
일부 포인팅 장치는 더 많은 버튼을 제공하거나 시뮬레이션합니다. 이러한 버튼을 나타내기 위해서는,
각 추가 버튼마다 값이 2배가 되어야 하며(이진 수열 8, 16, 32, ...),
이를 사용해야 합니다.
어떤 버튼 값 집합의 합은 고유한 숫자가 되므로, 콘텐츠 작성자는 비트 연산을 사용해
장치에 있는 임의 개수의 마우스 버튼에 대해 현재 눌린 버튼의 개수와 어떤 버튼들이 눌려 있는지
판별할 수 있습니다. 예를 들어 값 3은 왼쪽과 오른쪽 버튼이 동시에 눌려 있음을 나타내고,
값 5는 왼쪽과 가운데 버튼이 동시에 눌려 있음을 나타냅니다.
이 속성의 초기화되지 않은 값은
MUST 0이어야 합니다.
relatedTarget
이벤트 유형에 따라, UI 이벤트와 관련된 2차 EventTarget을(를)
식별하는 데 사용됩니다.
이 속성의 초기화되지 않은 값은
MUST null이어야 합니다.
키 값으로 수정자(modifier)의 상태를 조회합니다.
수정자 키이며 해당 수정자가 활성화되어 있으면 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입니다).
구현체는 마우스 이벤트를 생성할 때 현재 클릭 횟수를 유지해야 합니다. 이는 특정 시간 내에 포인팅 장치 버튼의 연속 클릭 횟수를 나타내는 0 이상의 정수여야 합니다. 이 횟수가 리셋되는 지연 시간은 환경 설정에 따라 달라집니다.
이 섹션의 알고리즘은 네이티브 플랫폼 OS가 다음을 제공한다고 가정합니다:
이러한 이벤트들에 대해, OS는 다음 정보를 제공할 수 있어야 합니다:
이 섹션은 개정이 필요합니다.
일반적으로 Event 인터페이스의 생성자 또는
Event 인터페이스를 상속받은 인터페이스의
생성자가 호출되면, [DOM]에 기술된 단계를 따라야 합니다. 하지만 MouseEvent 인터페이스는
Event 객체의 키 수정자에 대한 내부 상태를
초기화하기 위한 추가 딕셔너리 멤버들을 제공합니다. 구체적으로는,
getModifierState()
메서드로 조회되는 내부 상태입니다. 이 섹션은 새로운 MouseEvent 객체를 이러한 선택적 수정자
상태로
초기화하기 위한 [DOM]의 단계를 보완합니다.
MouseEvent 또는 아래 알고리즘을 사용해 이들로부터
파생된 객체를 구성하는 목적에서, 모든 MouseEvent 및
파생 객체는 내부 키 수정자 상태를 가지며, 이는
[UIEvents-Key]의
수정자 키 표에서 설명된
키 수정자 이름을 사용하여 설정 및 조회할 수 있습니다.
다음 단계는 [DOM]에서 이벤트를 구성하기 위해 정의된 알고리즘을 보완합니다:
Event가
MouseEvent 객체이거나 그로부터 파생된 객체이고,
생성자에 EventModifierInit
인자가 제공되었다면, 다음 하위 단계를 실행합니다:
EventModifierInit
인자에 대해, 딕셔너리 멤버가 문자열 "modifier"로 시작한다면,
키 수정자 이름을
"modifier" 접두사를 제외한 딕셔너리 멤버 이름으로 두고,
해당 Event 객체의
내부 키 수정자 상태 중
키 수정자 이름과 일치하는 항목을
해당 값으로 설정합니다.
이 섹션은 개정이 필요합니다.
UA는 전체 사용자 에이전트에 대해 공유되는 다음 값들을 유지해야 합니다.
마우스 버튼의 현재 상태를 추적하는 마우스 버튼 비트마스크.
UA는 윈도우에 대해 공유되는 다음 값들을 유지해야 합니다.
마지막 마우스
요소 값(초기값은 undefined)으로,
우리가 MouseEvent를 보낸 마지막 Element를 추적합니다.
마지막
마우스 DOM 경로 값(초기값은 비어 있음)으로,
가장 최근 마우스 이벤트가 전송될 당시의
마지막 마우스 요소의 조상 Element들의
스냅샷을 포함합니다.
이 섹션은 개정이 필요합니다.
MouseEvent에는 다양한 수정자 키의 상태를 추적하기 위해 사용되는
다음 내부 플래그들이 있습니다:
shift 플래그,
control
플래그,
alt 플래그,
altgraph
플래그,
그리고 meta 플래그.
이 플래그들은 마우스 이벤트 시점에 해당 수정자 키가 눌려 있었다면 설정됩니다.
이 섹션은 개정이 필요합니다.
elementFromPoint()를
반환합니다( 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을
eventType로 둡니다
EventTarget을
eventTarget로 둡니다
MouseEvent를 사용해 event로 둡니다
이 섹션은 개정이 필요합니다.
MouseEvent 타입을 담은 DOMString을
eventType로 둡니다
EventTarget을
eventTarget로 둡니다
MouseEvent를 사용해 event로 둡니다
이 섹션은 개정이 필요합니다.
MouseEvent로 둡니다
TODO.
type이 [
mousedown, mouseup ] 중 하나이면,
button을
mbutton로 MouseEvent button 속성
계산의
결과로 설정합니다
이 섹션은 개정이 필요합니다.
다른 버튼들은 0x08부터 추가할 수 있습니다.
이 섹션은 개정이 필요합니다.
mousedown과 mouseup 사이에 다른 마우스 이벤트가 발생할 수 있습니다.
이 섹션은 개정이 필요합니다.
플랫폼은 클릭을 생성하는 mouseup에 대해, 네이티브 마우스 업 처리 직후에 즉시 이를 호출해야 합니다.
이 섹션은 개정이 필요합니다.
EventTarget을
target로 둡니다
screenX가
정수 값이 아니면 반올림합니다.screenY가
정수 값이 아니면 반올림합니다.PointerEvents를 사용하며 좌표를 반올림하는 브라우저에 대한 정보는 pointerevents/100을 참고하세요.
어떤 "기본 동작"이든, 대상의 활성화 동작 알고리즘을 트리거함으로써 dispatch 중에 처리됩니다. 따라서 여기에서 이를 처리할 필요는 없습니다. 다만 기존 명세가 disabled/css-pointer-events/inert/...를 처리하는지 검증할 필요가 있습니다.
HTMLelement.click()을 처리하려면,
이 알고리즘을 native = null, target = HTMLelement로 호출합니다.
키보드로 시작된 클릭을 처리하려면, 이 알고리즘을 native = null, target = 현재 포커스된 요소로 호출합니다.
이 섹션은 개정이 필요합니다.
이는 더블 클릭을 생성하는 마우스 클릭에 대해, 네이티브 마우스 클릭 처리 직후에 즉시 호출되어야 합니다.
screenX가 정수 값이 아니면 반올림합니다.screenY가 정수 값이 아니면 반올림합니다.이 섹션은 개정이 필요합니다.
이 알고리즘은 PointerEvents의 dispatch에 대해, 현재 명시적으로 지정되어 있지 않다는 이유로 가정을 합니다. 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는 이 이벤트를 요소와 섀도우 루트에서 발생시킴.
이 명세에서 정의된 특정 마우스 이벤트는 서로에 대해 정해진 순서로 발생해야 합니다. 아래는 포인팅 장치의 커서가 어떤 요소 위로 이동할 때 반드시 발생해야 하는 이벤트 시퀀스를 보여줍니다:
| # | 이벤트 유형 | 요소 | 비고 |
|---|---|---|---|
| 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로 라벨링된 세 요소가 모두 동일한 크기와 웹 페이지 상의 동일한 절대 위치를 갖습니다. 요소 C는 B의 자식이고, B는 DOM에서 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
|
OPTIONAL, 여러 이벤트, 일부 제한 |
| 3 | mouseup
|
|
| 4 | click
|
|
| 5 | mousemove
|
OPTIONAL, 여러 이벤트, 일부 제한 |
| 6 | mousedown
|
|
| 7 | mousemove
|
OPTIONAL, 여러 이벤트, 일부 제한 |
| 8 | mouseup
|
|
| 9 | click
|
|
| 10 | dblclick
|
mousemove 이벤트가
mousedown와 mouseup 사이에 어느 정도(지연 시간, 정도, 거리, 개수)까지 허용되면서도
click 또는 dblclick
이벤트가 계속 발생할지는, 구현체/장치/플랫폼에 따라 달라집니다. 이러한 허용치는 포인팅 장치와 상호작용할 때 손이 떨리는 등
신체적 장애가 있는 사용자를 돕는 데 도움이 될 수 있습니다.
각 구현체는 적절한 히스테리시스
허용치를 결정할 것이며, 일반적으로는 연관된 mousedown
및
mouseup 이벤트의 이벤트 타깃이 동일한 요소이고,
그 사이에 mouseout 또는
mouseleave 이벤트가 개입하지 않는 경우
click 및 dblclick
이벤트를 발생시키는 것이 바람직합니다.
또한 연관된 mousedown 및 mouseup 이벤트 타깃이
서로 다른 경우에는,
가장 가까운 공통 포함 조상에서 click 및
dblclick 이벤트를 발생시키는 것이
바람직합니다.
mousedown 이벤트가 HTML 문서의 body
요소를 대상으로 했고, 대응되는 mouseup 이벤트가
문서 요소를 대상으로 했다면,
click 이벤트는
가장 가까운 공통 포함 조상이므로 문서
요소로 디스패치됩니다.
마우스 이벤트 시퀀스 중에 target(예: 대상 요소)이 DOM에서 제거되면, 시퀀스의 나머지 이벤트들은 그 요소에서 발생해서는 안 됩니다.
mousedown 이벤트의 결과로 대상 요소가 DOM에서 제거되면,
해당 요소에 대해 mouseup, click, 또는 dblclick 이벤트는 디스패치되지 않으며,
어떤 기본 활성화 이벤트도 발생하지 않습니다. 다만 mouseup 이벤트는,
초기 타깃 요소가 제거된 뒤 마우스에 노출되는 요소에서 여전히 디스패치됩니다. 마찬가지로 대상 요소가
mouseup 이벤트의 디스패치 중에 DOM에서 제거되면,
click 및 그 이후 이벤트들은 디스패치되지 않습니다.
| 유형 | auxclick
|
|---|---|
| 인터페이스 | PointerEvent
|
| 동기 / 비동기 | 동기 |
| 버블링 | 예 |
| 신뢰할 수 있는 대상 | Element |
| 취소 가능 | 예 |
| Composed | 예 |
| 기본 동작 | 상황에 따라 다름 |
| 컨텍스트 (신뢰할 수 있는 이벤트) |
|
auxclick 이벤트 유형은 사용자가 주 버튼이 아닌 포인터 버튼을
누르고 놓을 때, 또는 그러한 동작을 시뮬레이션하는 방식으로 포인터를 활성화할 때,
포인터가 가리키는 최상위
이벤트 대상에 MUST 디스패치되어야 합니다. 마우스 버튼의 작동 방식은
포인팅 장치와 환경 설정에 따라 달라지며, 예를 들어 화면 위치 또는 포인팅 장치 버튼의 누름과 놓음 사이의
지연 시간에 의존할 수도 있습니다(MAY).
auxclick 이벤트는 주 버튼이 아닌 포인터 버튼에 대해서만
발생해야 합니다(즉 button 값이 0이 아니고,
buttons 값이 1보다 큰 경우).
주 버튼(표준 마우스의 왼쪽 버튼과 같은)은 auxclick 이벤트를 발생시키면 안 됩니다.
주 버튼과 연관된 대응 이벤트는 click을 참고하세요.
auxclick 이벤트는 동일한 요소에서
mousedown 및
mouseup 이벤트가 먼저 발생한 뒤에 이어질 수도 있습니다
(텍스트 노드 같은 다른 노드 유형 간의 변경은 무시). 환경 설정에 따라,
포인팅 장치 버튼의 누름과 놓음 사이에
mouseover,
mousemove, 및 mouseout 이벤트 유형 중 하나 이상이 발생하는 경우에도
auxclick 이벤트가
디스패치될 수도 있습니다(MAY).
auxclick 이벤트 유형의 기본 동작은
이벤트의 target과
button 또는 buttons 속성의 값에 따라 달라집니다.
auxclick 이벤트 유형의 전형적인
기본 동작은 다음과 같습니다:
myLink.addEventListener("auxclick", function(e) {
if (e.button === 1) {
// This would prevent the default behavior which is for example
// opening a new tab when middle clicking on a link.
e.preventDefault();
// Do something else to handle middle button click like taking
// care of opening link or non-link buttons in new tabs in a way
// that fits the app. Other actions like closing a tab in a tab-strip
// which should be done on the click action can be done here too.
}
});
오른쪽 버튼의 경우, auxclick 이벤트는
어떤 contextmenu 이벤트 이후에 디스패치됩니다.
일부 사용자 에이전트는 컨텍스트 메뉴가 표시되는 동안 모든 입력 이벤트를 삼켜 버리므로,
그런 시나리오에서는 auxclick을 애플리케이션에서 사용할 수 없을 수 있습니다.
더 명확한 설명은 예 7을 참고하세요.
myDiv.addEventListener("contextmenu", function(e) {
// This call makes sure no context menu is shown
// to interfere with page receiving the events.
e.preventDefault();
});
myDiv.addEventListener("auxclick", function(e) {
if (e.button === 2) {
// Do something else to handle right button click like opening a
// customized context menu inside the app.
}
});
| 유형 | click
|
|---|---|
| 인터페이스 | PointerEvent
|
| 동기 / 비동기 | 동기 |
| 버블링 | 예 |
| 신뢰할 수 있는 대상 | Element |
| 취소 가능 | 예 |
| Composed | 예 |
| 기본 동작 | 상황에 따라 다름 |
| 컨텍스트 (신뢰할 수 있는 이벤트) |
|
click 이벤트 유형은 사용자가 주 포인터 버튼을 누르고 놓을 때,
또는 그러한 동작을 시뮬레이션하는 방식으로 포인터를 활성화할 때,
포인터가 가리키는 최상위
이벤트 대상에 MUST 디스패치되어야 합니다. 마우스 버튼의 작동 방식은
포인팅 장치와 환경 설정에 따라 달라지며, 예를 들어 화면 위치 또는 포인팅 장치 버튼의 누름과 놓음 사이의
지연 시간에 의존할 수도 있습니다(MAY).
click 이벤트는 주 포인터 버튼에 대해서만 발생해야 합니다
(즉 button 값이 0이고,
buttons 값이 1인 경우).
2차 버튼(표준 마우스의 가운데 또는 오른쪽 버튼과 같은)은
click 이벤트를 발생시키면 안 됩니다.
주 버튼이 아닌 버튼과 연관된 대응 이벤트는 auxclick을 참고하세요.
click 이벤트는 동일한 요소에서
mousedown 및
mouseup 이벤트가 먼저 발생한 뒤에 이어질 수도 있습니다
(예: 텍스트 노드 같은 다른 노드 유형 간의 변경은 무시). 환경 설정에 따라,
포인팅 장치 버튼의 누름과 놓음 사이에
mouseover,
mousemove, 및 mouseout 이벤트 유형 중 하나 이상이 발생하는 경우에도
click 이벤트가
디스패치될 수도 있습니다(MAY).
또한 click 이벤트 뒤에는
dblclick 이벤트가 뒤따를 수도 있습니다(MAY).
사용자가 큰 line-height로 스타일링된 <p> 요소의 텍스트 노드 자식에서 마우스를 누른 다음,
마우스를 약간 이동해 더 이상 텍스트가 포함된 영역 위에 있지는 않지만 여전히 그 <p> 요소의
포함 블록 안(즉 동일한 텍스트 블록의 줄 사이에는 있지만, 텍스트 노드 자체 위는 아님)에 있고,
이후 마우스를 놓는다면, 사용자가 동일 요소의 범위 안에 머물렀기 때문에
(일반적인 히스테리시스의 시간적 허용 범위 내의 click에 해당한다면)
여전히 click 이벤트가 트리거될 가능성이 높습니다.
사용자 에이전트가 생성한 마우스 이벤트는 텍스트 노드에서는 디스패치되지 않는다는 점에 유의하세요.
포인터 장치와 연관되는 것 외에도,
click 이벤트 유형은 요소 활성화의 일부로서
MUST 디스패치되어야 합니다.
최대한의 접근성을 위해, 콘텐츠 작성자는 커스텀 컨트롤의 활성화 동작을 정의할 때
click 이벤트 유형을,
장치에 더 특화된 mousedown 또는 mouseup 같은 다른 포인팅 장치 이벤트 유형 대신
사용하는 것이 권장됩니다. click 이벤트 유형은 포인터 장치(예: 마우스)에서 유래했지만,
이후 구현 개선을 통해 그 연관성을 넘어 확장되었으며, 요소 활성화를 위한 장치 독립적 이벤트 유형으로
볼 수 있습니다.
click 이벤트 유형의 기본 동작은
이벤트의 target과
button 또는 buttons 속성의 값에 따라 달라집니다.
click 이벤트 유형의 전형적인
기본 동작은 다음과 같습니다:
| 유형 | dblclick |
|---|---|
| 인터페이스 | MouseEvent |
| 동기 / 비동기 | 동기 |
| 버블링 | 예 |
| 신뢰할 수 있는 대상 | Element |
| 취소 가능 | 예 |
| Composed | 예 |
| 기본 동작 | 없음 |
| 컨텍스트 (신뢰할 수 있는 이벤트) |
|
사용자 에이전트는 포인팅 장치의
주 버튼이 어떤 요소 위에서 두 번 클릭되었을 때 이 이벤트를 MUST 디스패치해야 합니다.
더블 클릭의 정의는 환경 설정에 따라 달라지지만,
mousedown, mouseup, 및 dblclick 사이에서 이벤트 타깃은 동일해야 합니다(MUST).
클릭과 더블 클릭이 동시에 발생하는 경우, 이 이벤트 유형은
click 이벤트 유형 이후에 MUST
디스패치되어야 하며,
그 외의 경우에는 mouseup 이벤트 유형 이후에 디스패치되어야 합니다.
click 이벤트와 마찬가지로,
dblclick 이벤트는 주 포인터 버튼에 대해서만 발생해야 합니다.
2차 버튼은 dblclick 이벤트를 발생시키면 안 됩니다.
click 이벤트 유형과 마찬가지로,
dblclick 이벤트 유형의 기본 동작은
이벤트의 target과
button
또는 buttons 속성의 값에 따라 달라집니다.
dblclick 이벤트 유형의 전형적인
기본 동작은
click 이벤트 유형의 것과 일치합니다.
| 유형 | mousedown
|
|---|---|
| 인터페이스 | MouseEvent |
| 동기 / 비동기 | 동기 |
| 버블링 | 예 |
| 신뢰할 수 있는 대상 | Element |
| 취소 가능 | 예 |
| Composed | 예 |
| 기본 동작 | 상황에 따라 다름: 드래그/드롭 작업 시작; 텍스트 선택 시작; 스크롤/팬 상호작용 시작 (지원되는 경우 가운데 마우스 버튼과 조합) |
| 컨텍스트 (신뢰할 수 있는 이벤트) |
|
| 유형 | mouseenter
|
|---|---|
| 인터페이스 | MouseEvent |
| 동기 / 비동기 | 동기 |
| 버블링 | 아니요 |
| 신뢰할 수 있는 대상 | Element |
| 취소 가능 | 아니요 |
| Composed | 아니요 |
| 기본 동작 | 없음 |
| 컨텍스트 (신뢰할 수 있는 이벤트) |
|
mouseover와
유사하지만, 버블링되지 않으며, 포인팅 장치가 한 요소에서 그 자손 요소 중 하나의 경계로 이동할 때에는
디스패치되어서는 안 됩니다(MUST NOT).
이 이벤트 유형과 CSS의
:hover 의사 클래스 [CSS2]
사이에는
유사점이 있습니다.
또한 mouseleave 이벤트 유형도 참고하세요.
| 유형 | mouseleave
|
|---|---|
| 인터페이스 | MouseEvent |
| 동기 / 비동기 | 동기 |
| 버블링 | 아니요 |
| 신뢰할 수 있는 대상 | Element |
| 취소 가능 | 아니요 |
| Composed | 아니요 |
| 기본 동작 | 없음 |
| 컨텍스트 (신뢰할 수 있는 이벤트) |
|
mouseout와
유사하지만, 버블링되지 않으며, 포인팅 장치가 요소의 경계와 그 모든 자식의 경계를 떠나기 전까지는
디스패치되어서는 안 됩니다(MUST NOT).
이 이벤트 유형과 CSS의
:hover 의사 클래스 [CSS2]
사이에는
유사점이 있습니다.
또한 mouseenter 이벤트 유형도 참고하세요.
| 유형 | mousemove
|
|---|---|
| 인터페이스 | MouseEvent |
| 동기 / 비동기 | 동기 |
| 버블링 | 예 |
| 신뢰할 수 있는 대상 | Element |
| 취소 가능 | 예 |
| Composed | 예 |
| 기본 동작 | 없음 |
| 컨텍스트 (신뢰할 수 있는 이벤트) |
|
mousemove
이벤트가 발생하는 것이 바람직합니다(SHOULD).
구현체는 반응성과 성능의 균형을 맞추기 위해 최적의 빈도율을 결정하는 것이 권장됩니다.
브라우저와 같은 일부 구현 환경에서는, 사용자가 드래그 작업을 시작했고(예: 마우스 버튼이 눌린 상태),
포인팅 장치가 사용자 에이전트의 경계를 벗어났더라도
mousemove 이벤트가 계속 발생할 수 있습니다.
이 이벤트는 DOM Level 2 Events에서는 취소 불가로 명시되어 있었지만, 사용자 에이전트 간의 기존 상호운용성을 반영하기 위해 변경되었습니다.
| 유형 | mouseout
|
|---|---|
| 인터페이스 | MouseEvent |
| 동기 / 비동기 | 동기 |
| 버블링 | 예 |
| 신뢰할 수 있는 대상 | Element |
| 취소 가능 | 예 |
| Composed | 예 |
| 기본 동작 | 없음 |
| 컨텍스트 (신뢰할 수 있는 이벤트) |
|
mouseleave와 유사하지만,
버블링되며, 포인팅 장치가 한 요소에서 그 자손 요소 중 하나의 경계로 이동할 때
디스패치되어야 합니다(MUST).
mouseover 이벤트 유형도 참고하세요.
| 유형 | mouseover
|
|---|---|
| 인터페이스 | MouseEvent |
| 동기 / 비동기 | 동기 |
| 버블링 | 예 |
| 신뢰할 수 있는 대상 | Element |
| 취소 가능 | 예 |
| Composed | 예 |
| 기본 동작 | 없음 |
| 컨텍스트 (신뢰할 수 있는 이벤트) |
|
mouseenter와 유사하지만,
버블링되며, 동일한 이벤트
리스너 인스턴스에 대해
조상 요소가 동일한 target인 요소의 경계로
포인팅 장치가 이동할 때
디스패치되어야 합니다(MUST).
mouseout 이벤트 유형도 참고하세요.
| 유형 | mouseup
|
|---|---|
| 인터페이스 | MouseEvent |
| 동기 / 비동기 | 동기 |
| 버블링 | 예 |
| 신뢰할 수 있는 대상 | Element |
| 취소 가능 | 예 |
| Composed | 예 |
| 기본 동작 | 없음 |
| 컨텍스트 (신뢰할 수 있는 이벤트) |
|
브라우저와 같은 일부 구현 환경에서는,
포인팅 장치가 사용자 에이전트의 경계를 벗어났더라도
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포인터의 접촉 기하(contact geometry)에 대한 너비(X축 크기)이며,
CSS 픽셀 단위입니다([CSS21]
참조).
이 값은 동일 포인터에 대해서도 각 이벤트마다 갱신될 수 있습니다(MAY).
일반적인 마우스처럼 접촉 기하가 보통 없는 입력의 경우, 그리고 입력의 실제 기하가 하드웨어에 의해
감지되지 않는 경우에는, 사용자
에이전트는 기본값
1을 반환해야 합니다(MUST).
height포인터의 접촉 기하(contact geometry)에 대한 높이(Y축 크기)이며,
CSS 픽셀 단위입니다([CSS21]
참조).
이 값은 동일 포인터에 대해서도 각 이벤트마다 갱신될 수 있습니다(MAY).
일반적인 마우스처럼 접촉 기하가 보통 없는 입력의 경우, 그리고 입력의 실제 기하가 하드웨어에 의해
감지되지 않는 경우에는, 사용자
에이전트는 기본값
1을 반환해야 합니다(MUST).
pressure[0,1] 범위에서 정규화된 포인터 입력의 압력입니다. 여기서 0과 1은
각각 하드웨어가 감지할 수 있는 최소 및 최대 압력을 나타냅니다. 압력을 지원하지 않는 하드웨어 및
플랫폼의 경우, 활성 버튼 상태에서는 값이
0.5여야 하며(MUST), 그 외에는 0이어야 합니다.
tangentialPressure정규화된 접선 압력(배럴 압력이라고도 함)으로, 일반적으로 추가 제어 장치(예: 에어브러시 스타일러스의 핑거 휠)에
의해 설정되며, [-1,1] 범위의 포인터 입력 값입니다. 여기서 0은 제어
장치의 중립 위치입니다. 일부 하드웨어는 [0,1] 범위의 양수 값만 지원할 수 있다는
점에 유의하세요. 접선 압력을 지원하지 않는 하드웨어 및 플랫폼의 경우, 값은 0이어야
합니다(MUST).
tiltXY-Z 평면과, 트랜스듀서(예: 펜/스타일러스) 축과 Y축을 모두 포함하는 평면 사이의 평면각(도 단위,
[-90,90] 범위)입니다. 양의 tiltX는 X 값이 증가하는 방향으로 오른쪽을
뜻합니다. tiltX는 tiltY와 함께 사용하여 디지타이저가 있는
트랜스듀서의 법선에서 벗어난 기울기를 나타낼 수 있습니다. 기울기 또는 각도를 보고하지 않는 하드웨어 및
플랫폼의 경우, 값은 0이어야 합니다(MUST).
tiltX.
tiltYX-Z 평면과, 트랜스듀서(예: 펜/스타일러스) 축과 X축을 모두 포함하는 평면 사이의 평면각(도 단위,
[-90,90] 범위)입니다. 양의 tiltY는 Y 값이 증가하는 방향으로 사용자
쪽을 뜻합니다. tiltY는 tiltX와 함께 사용하여 디지타이저가 있는
트랜스듀서의 법선에서 벗어난 기울기를 나타낼 수 있습니다. 기울기 또는 각도를 보고하지 않는 하드웨어 및
플랫폼의 경우, 값은 0이어야 합니다(MUST).
tiltY.
twist트랜스듀서(예: 펜/스타일러스)가 자신의 주축을 중심으로 시계 방향으로 회전한 값(도 단위,
[0,359] 범위)입니다. 회전을 보고하지 않는 하드웨어 및 플랫폼의 경우, 값은
0이어야 합니다(MUST).
altitudeAngle트랜스듀서(예: 펜/스타일러스)의 고도(라디안 단위)이며, [0,π/2] 범위입니다 —
여기서 0은 표면(X-Y 평면)과 평행함을, π/2는 표면에 수직임을
나타냅니다. 기울기 또는 각도를 보고하지 않는 하드웨어 및 플랫폼의 경우, 값은 π/2여야
합니다(MUST).
altitudeAngle의 기본값은 π/2이며,
이는 트랜스듀서가 표면에 수직으로 놓이도록 합니다.
이는 Touch Events - Level
2 명세의 altitudeAngle 속성 정의(기본값이 0)와
다릅니다.
altitudeAngle이 π/4인 경우(X-Y 평면으로부터 45도).
azimuthAngle트랜스듀서(예: 펜/스타일러스)의 방위각(라디안 단위)이며, [0, 2π] 범위입니다 —
여기서 0은 X-Y 평면에서 트랜스듀서의 캡이 X 값이 증가하는 방향을 가리키는 것을
나타냅니다(수직으로 내려다볼 때 "3시" 방향). 값은 시계 방향으로 갈수록 점진적으로 증가합니다
(π/2는 "6시", π는 "9시", 3π/2는 "12시").
트랜스듀서가 표면에 완전히 수직일 때(altitudeAngle이 π/2),
값은 0이어야 합니다(MUST).
기울기 또는 각도를 보고하지 않는 하드웨어 및 플랫폼의 경우에도 값은 0이어야 합니다(MUST).
azimuthAngle이 π/6인 경우("4시").pointerType이벤트를 발생시킨 장치 유형(예: mouse, pen, touch)을 나타냅니다. 사용자 에이전트가 마우스,
펜/스타일러스 또는 터치 입력 장치에 대해 포인터
이벤트를 발생시키려면, pointerType 값은 다음 표에 따라야 합니다(MUST):
| 포인터 장치 유형 | pointerType 값 |
|---|---|
| 마우스 | mouse |
| 펜 / 스타일러스 | pen |
| 터치 접촉 | touch |
장치 유형을 사용자 에이전트가 감지할 수 없는 경우, 값은 빈 문자열이어야 합니다(MUST). 사용자 에이전트가 위에
나열된 것 이외의 포인터 장치 유형을
지원한다면, 서로 다른 장치 유형 간 이름 충돌을 피하기 위해 pointerType 값은
벤더 접두어를 붙이는 것이 권장됩니다(SHOULD).
향후 명세는 다른 장치 유형을 위한 추가적인 규범 값들을 제공할 수도 있습니다(MAY).
pointerType 사용 데모는 예
2를 참고하세요. 또한 개발자는 사용자 에이전트가 자체 커스텀
pointerType 값을 구현했을 수 있는 경우와, pointerType이 단순히 빈
문자열인 상황을 모두 포괄할 수 있도록 어떤 형태로든 기본 처리(default handling)를 포함해야
한다는 점에 유의하세요.
isPrimary포인터가 이 포인터 유형의 주 포인터를 나타내는지 여부를 나타냅니다.
persistentDeviceId포인팅 장치에 대한 고유 식별자입니다. 하드웨어가 여러 포인터를 지원하는 경우, 포인팅 장치에서 생성된 포인터
이벤트는 세션 동안 해당 포인터들이 고유하게 식별 가능할 때에만 persistentDeviceId를
가져야 합니다(MUST).
포인터가 고유하게 식별 가능하다면, 그 포인팅 장치에 할당된 persistentDeviceId는 세션의
나머지 기간 동안 일정하게 유지됩니다. persistentDeviceId 값 0은 생성
장치를 식별할 수 없는 이벤트를 나타내기 위해 예약되어 사용되어야 합니다(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를 상속합니다.
또한 CSSOM View Module의 제안된 확장은
각 좌표 속성을 long에서 double로 변경하여 소수 좌표를 허용합니다.
이 제안된 확장을
PointerEvent에는 이미 구현했지만,
일반 MouseEvent에는 구현하지 않은 사용자
에이전트의 경우,
click,
auxclick, 및 contextmenu 이벤트에 관한 추가 요구사항이 있습니다.
다중 포인터(예: 멀티터치) 시나리오에서, isPrimary 속성은 각 포인터 유형에 대해
활성 포인터 집합 중 마스터 포인터를 식별하는 데 사용됩니다.
pointerType당 하나)가
주 포인터로 간주됩니다. 예를 들어 터치 접촉과 마우스 커서가 동시에 움직이면, 둘 다 주 포인터로 간주되는
포인터가 생성됩니다.
isPrimary 값이 false인 상태로 다른 포인터에 대한 포인터
이벤트를 발생시킬 수도 있습니다(MAY).e라는 이름의 포인터 이벤트를 발생시킨다는 것은,
이벤트를 발생시키는 것을
의미하며, PointerEvent를 사용해
PointerEvent 인터페이스 및
속성과 기본 동작에 정의된 대로 속성이 설정된
상태로 e라는 이름의 이벤트를 발생시키는 것을 말합니다.
이벤트가 gotpointercapture,
lostpointercapture,
click, auxclick 또는 contextmenu 이벤트가 아니라면,
이 PointerEvent에 대해 대기 중인 포인터 캡처 처리 단계를
실행합니다.
이벤트가 발생되는 대상을 다음과 같이 대상 결정합니다:
targetDocument를 대상의 노드 문서 [DOM]로 둡니다.
이벤트가 pointerdown,
pointermove, 또는
pointerup이라면,
이벤트의 pointerId에 대한
활성 문서를 targetDocument로 설정합니다.
이벤트가 pointerdown이고,
연결된 장치가 직접 조작 장치이며, 대상이
Element라면,
암시적 포인터 캡처에 설명된 대로, 이
pointerId에 대해 대상 요소로
포인터 캡처를 설정합니다.
이 이벤트를 발생시키기 전에, 사용자
에이전트는
이벤트 순서 보장 [UIEVENTS]의 목적을 위해,
대상을 previousTarget에서 포인팅 장치가 그 위로 이동해 온 것처럼 취급하는 것이 권장됩니다(SHOULD). needsOverEvent 플래그가 설정되어 있으면, 대상 요소가
동일하더라도 pointerover 이벤트가 필요합니다.
결정된 대상에 이벤트를 발생시킵니다.
결정된 대상을 해당 포인터에 대한 previousTarget으로 저장하고,
needsOverEvent 플래그를 false로 재설정합니다.
어느 시점에서든 previousTarget이 더 이상 연결됨
[DOM]
상태가 아니게 되면,
previousTarget을 previousTarget으로 이벤트를 디스패치하는 것에 해당하는 이벤트 경로를
따라 가장 가까운 여전히 연결됨
[DOM]
상태인 부모로 갱신하고,
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인 것이 권장되며(SHOULD),
위 표의 다른 모든 포인터 이벤트에 대해서는 true인 것이 권장됩니다(SHOULD).
위 표의 모든 포인터 이벤트에 대해,
detail
[UIEVENTS] 속성은 0인 것이 권장됩니다(SHOULD).
fromElement 및 toElement를 노출합니다. 우리는 그러한 사용자 에이전트가,
작성자를 표준 대안(target 및 relatedTarget) 사용으로 전환시키기 위해,
PointerEvent에서 상속된 이러한 속성 값들을 null로 설정하도록 권장합니다.
MouseEvent의 relatedTarget과
유사하게, relatedTarget은 포인터가 막 떠난 요소의 경계를 나타내는 요소로 초기화되어야 합니다(예:
pointerover 또는 pointerenter
이벤트의 경우). 또는 포인터가 들어가고 있는 요소의 경계를 나타내는 요소로 초기화되어야 합니다(예:
pointerout 또는
pointerleave 이벤트의 경우).
다른 포인터 이벤트에 대해서는 이 값의 기본값은 null입니다. 요소가 포인터 캡처를 받으면, 해당 포인터에 대한
이후 모든 이벤트는 캡처 중인 요소의 경계 안에 있는 것으로 간주된다는 점에 유의하세요.
gotpointercapture
및 lostpointercapture
이벤트의 경우, 위 표에 정의된 것들을 제외한 모든 속성은 사용자 에이전트가
대기 중인 포인터 캡처 처리 단계를 실행하고
gotpointercapture
및 lostpointercapture
이벤트를 발생시키게 만든 포인터 이벤트와 동일해야 합니다.
사용자 에이전트는
암시적으로 포인터 캡처를 해제할 때뿐 아니라,
gotpointercapture
또는 lostpointercapture
가 아닌 포인터 이벤트를 발생시킬 때에도 다음 단계를 실행해야 합니다(MUST).
lostpointercapture라는
이름의 포인터 이벤트를
포인터 캡처 대상 오버라이드 노드에서 발생시킵니다.
gotpointercapture라는
이름의 포인터 이벤트를
대기 중인
포인터 캡처 대상 오버라이드에서 발생시킵니다.
click,
auxclick, 및 contextmenu 이벤트 절에서 정의한 바와 같이,
lostpointercapture 이벤트가
디스패치된 이후에도,
해당하는 click, auxclick 또는 contextmenu 이벤트가 있다면,
그 이벤트는 여전히 캡처 중인 대상(capturing target)으로 디스패치됩니다.
사용자 에이전트는 웹 페이지가
특정 pointerId에 대한 포인터 이벤트를 더 이상
계속 받을 가능성이 낮다고 감지하면 포인터 이벤트 스트림을 억제해야 합니다(MUST). 다음 시나리오 중 어느 하나라도 이 조건을 만족합니다(추가 시나리오가 있을 수도
있습니다(MAY)):
touch-action CSS 속성 절을 참고하세요.
사용자 에이전트가 포인터 이벤트 스트림을 억제할 수도 있는(MAY) 다른 시나리오에는 다음이 포함됩니다:
이러한 시나리오를 감지하는 방법은 본 명세의 범위를 벗어납니다.
사용자 에이전트는 포인터 이벤트 스트림을 억제하기 위해 다음 단계를 실행해야 합니다(MUST):
pointercancel
이벤트를 발생시킵니다.pointerout 이벤트를 발생시킵니다.pointerleave
이벤트를 발생시킵니다.화면 표면에 대해 상대적으로 이동했거나 속성 중 일부가 변경된 포인팅 장치는
포인터 이벤트 유형에 정의된 대로 다양한 이벤트를 발생시킵니다.
화면 표면에 대해 이동하지도 않았고 어떤 속성도 변경되지 않은 정지 포인팅 장치의 경우,
사용자 에이전트는
포인터에 대한 히트 테스트 대상을 영향을 준 레이아웃 변경 이후, 특정 경계 이벤트를 발생시켜야
합니다(MUST).
자세한 내용은 pointerover,
pointerenter,
pointerout 및
pointerleave를 참고하세요.
사용자 에이전트는 성능상의
이유로 이러한 경계 이벤트의 발생을 지연시킬 수도 있습니다(MAY)
(예: 너무 많은 히트 테스트나 경계 이벤트 리스너로 인한 레이아웃 변경을 피하기 위해).
pointermove 이벤트를 발생시키지 않습니다.
포인터 이벤트는 X-Y 평면에 대한 트랜스듀서의 방향을 표현하기 위한 서로 보완적인 두 속성 집합을 포함합니다:
tiltX / tiltY(원래 포인터 이벤트 명세에서 도입됨) 및
azimuthAngle / altitudeAngle(Touch Events - Level 2 명세에서 채택됨).
특정 하드웨어와 플랫폼에 따라, 사용자 에이전트는 화면 평면에 대한 트랜스듀서 방향 값 집합 중 하나만 받을 가능성이
큽니다 — 즉 tiltX / tiltY 또는
altitudeAngle / azimuthAngle. 사용자 에이전트는 이 값들을 변환하기 위해 다음
알고리즘을 사용해야 합니다(MUST).
사용자 에이전트가 azimuthAngle / altitudeAngle로부터
tiltX / tiltY를 계산할 때는,
Math.round [ECMASCRIPT] 규칙을 사용하여 최종 정수 값을
반올림하는 것이 권장됩니다(SHOULD).
/* Converting between tiltX/tiltY and altitudeAngle/azimuthAngle */
function spherical2tilt(altitudeAngle, azimuthAngle) {
const radToDeg = 180/Math.PI;
let tiltXrad = 0;
let tiltYrad = 0;
if (altitudeAngle == 0) {
// the pen is in the X-Y plane
if (azimuthAngle == 0 || azimuthAngle == 2*Math.PI) {
// pen is on positive X axis
tiltXrad = Math.PI/2;
}
if (azimuthAngle == Math.PI/2) {
// pen is on positive Y axis
tiltYrad = Math.PI/2;
}
if (azimuthAngle == Math.PI) {
// pen is on negative X axis
tiltXrad = -Math.PI/2;
}
if (azimuthAngle == 3*Math.PI/2) {
// pen is on negative Y axis
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;
// calculate 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) {
// not enough information to calculate azimuth
azimuthAngle = 0;
} else {
// Non-boundary case: neither tiltX nor tiltY is equal to 0 or +-90
const tanX = Math.tan(tiltXrad);
const tanY = Math.tan(tiltYrad);
azimuthAngle = Math.atan2(tanY, tanX);
if (azimuthAngle < 0) {
azimuthAngle += 2*Math.PI;
}
}
// calculate 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 {
// Non-boundary case: neither tiltX nor tiltY is equal to 0 or +-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로 둡니다.MouseEvent에서
PointerEvent 생성을 "pointerout" 및 mouseout로 실행한 결과로 둡니다.TODO.
target으로 둡니다.MouseEvent로 둡니다.MouseEvent에서
PointerEvent 생성을 "pointerout" 및 mouseout로 실행한 결과로 둡니다.TODO.
target으로 둡니다.MouseEvent로 둡니다.MouseEvent에서
PointerEvent 생성을 "pointerout" 및 mouseout로 실행한 결과로 둡니다.TODO.
target으로 둡니다.MouseEvent로 둡니다.MouseEvent에서
PointerEvent 생성을 "pointerout" 및 mouseout로 실행한 결과로 둡니다.TODO.
target으로 둡니다.MouseEvent로 둡니다.
이것이 pointermove와 pointerrawupdate를 보낼 수 있나요? 아니면 2개의 메서드가 필요한가요?
pointermove 이벤트가 병합되는 방식(coalesced)을 제대로 정의하려면 무엇이 필요한가요?
MouseEvent에서
PointerEvent 생성을 "pointerout" 및 mouseout로 실행한 결과로 둡니다.TODO.
target으로 둡니다.MouseEvent로 둡니다.
mousedown 이벤트와 달리, pointerdown
이벤트는 여러 버튼이 눌릴 때 중첩되지 않습니다.
MouseEvent가 전달되는 이유는 그 필드들을
PointerEvent에 복사할 수 있게 하기 위함입니다.
MouseEvent에서
PointerEvent 생성을 "pointerout" 및 mouseout로 실행한 결과로 둡니다.
TODO.
target으로 둡니다.MouseEvent로 둡니다.
target으로 둡니다.MouseEvent로 둡니다.
mouseup 이벤트와 달리, pointerup 이벤트는 여러 버튼이 눌릴 때 중첩되지
않습니다. MouseEvent가
전달되는 이유는 그 필드들을 PointerEvent에 복사할 수 있게 하기 위함입니다.
MouseEvent에서
PointerEvent 생성을 "pointerout" 및 mouseout로 실행한 결과로 둡니다.
TODO.
target으로 둡니다.아래는 이 명세에서 정의하는 이벤트 유형입니다.
주 포인터의 경우, 이 이벤트들(gotpointercapture 및 lostpointercapture는 예외)은 호환성 마우스 이벤트도 함께 발생시킬 수 있습니다.
사용자 에이전트는 MUST 다음 중 어느 하나라도 발생하면 포인터 이벤트를
발생시켜
pointerover라는 이름의 이벤트를 발생시켜야 합니다:
pointerdown 이벤트를, 호버를 지원하지 않는 장치에 대해 사용자 에이전트가
발생시키기 전에( pointerdown 참조 ).사용자 에이전트는 MUST 다음 중 어느 하나라도 발생하면 포인터 이벤트를
발생시켜
pointerenter라는 이름의 이벤트를 발생시켜야 합니다:
pointerdown 이벤트를, 호버를 지원하지 않는 장치에 대해 사용자 에이전트가
발생시키기 전에( pointerdown 참조 ).pointerover와 유사하지만 두 가지
차이가 있습니다:
pointerenter는 버블링되지 않으며, 디스패치는
자손 요소의 히트 테스트 경계까지 고려합니다.
mouseenter 이벤트, 그리고
[CSS21]에
설명된
CSS :hover 의사 클래스와 유사한 점이 있습니다.
또한 pointerleave 이벤트도
참고하세요.
사용자 에이전트는 포인터가
활성 버튼 상태로 들어가면 MUST 포인터 이벤트를 발생시켜
pointerdown라는 이름의 이벤트를 발생시켜야 합니다. 마우스의
경우 이는 장치가 어떤 버튼도 눌리지 않은 상태에서 적어도 하나의 버튼이 눌린 상태로 전이될 때입니다. 터치의 경우
이는 디지타이저와 물리적으로 접촉이 이루어질 때입니다. 펜의 경우 이는 (어떤 버튼도
눌리지 않은 상태에서) 펜이 디지타이저와 물리적으로 접촉을 하거나, 호버 중에 어떤 버튼도 눌리지 않은 상태에서
적어도 하나의 버튼이 눌린 상태로 전이될 때입니다.
pointerdown 및 pointerup이 mousedown 및
mouseup과 동일한 모든 상황에서 발생되지 않음을 의미합니다. 자세한 내용은
코디드 버튼을 참고하세요.
호버를 지원하지 않는 입력 장치의 경우,
사용자 에이전트는 또한
MUST 포인터 이벤트를 발생시켜
pointerover라는 이름의 이벤트를 발생시킨 다음,
포인터 이벤트 pointerenter를 발생시키고,
그 후에 pointerdown 이벤트를
디스패치해야 합니다.
isPrimary 속성이 true인 경우)
pointerdown 이벤트를 취소함으로써 특정
호환성 마우스 이벤트의 발생을 방지할 수 있습니다.
이는 포인터에 PREVENT MOUSE EVENT 플래그를 설정합니다. 다만 이는
mouseover, mouseenter, mouseout, 또는
mouseleave 이벤트의 발생을 방지하지는 않습니다.
사용자 에이전트는 포인터가
pointerdown 또는 pointerup 이벤트를 발생시키지 않는 속성들 중 어떤 것이든
변경하면 MUST 포인터 이벤트를 발생시켜
pointermove라는 이름의 이벤트를 발생시켜야 합니다. 여기에는
좌표, 압력, 접선 압력, 기울기, 트위스트, 접촉 기하(width 및 height) 또는
코디드 버튼의 어떤 변경도 포함됩니다.
사용자 에이전트는(예: 성능상의 이유로) pointermove 이벤트의 디스패치를 지연할
수도 있습니다(MAY).
병합된 이벤트 정보는, 단일로 디스패치된
pointermove 이벤트에 대해
getCoalescedEvents 메서드를 통해
노출됩니다.
이러한 이벤트들의 최종 좌표는 이벤트의 대상을 찾는 데 사용되어야 합니다.
사용자 에이전트는 포인터가
pointerdown 또는 pointerup 이벤트를 발생시키지 않는 속성들 중 어떤 것이든 변경할 때,
MUST 포인터 이벤트를 발생시켜
pointerrawupdate라는 이름의
이벤트를 발생시켜야 하며, 또한 보안 컨텍스트 내에서만
이를 수행해야 합니다.
이러한 속성들의 목록은 pointermove 이벤트를 참고하세요.
pointermove와는 달리, 사용자
에이전트는 SHOULD 가능한 한 빨리, 그리고 JavaScript가 이벤트를 처리할 수 있는
빈도만큼 자주 pointerrawupdate 이벤트를
디스패치해야 합니다.
pointerrawupdate 이벤트의 target은,
pointermove 이벤트가 지연되거나 병합될 수 있고, 이벤트의
대상을 찾는 데 사용되는 최종 위치가 병합된 이벤트들과 다를 수 있기 때문에,
pointermove 이벤트의 것과 다를 수 있습니다.
동일한 pointerId를 가지며 아직
이벤트
루프에서
디스패치되지 않은 다른 pointerrawupdate가 이미 있는
경우,
사용자 에이전트는
새로운 pointerrawupdate를 새
태스크를 만드는 대신
그 이벤트와 병합할 수도 있습니다(MAY).
이는 pointerrawupdate가
병합된 이벤트를 가지게 만들 수 있으며,
이벤트가 이벤트 루프에서 처리되는 즉시
하나의 pointerrawupdate 이벤트의
병합된 이벤트로 모두 전달됩니다.
자세한 내용은 getCoalescedEvents를 참고하세요.
pointerrawupdate와 pointermove의 순서에 관해서는,
플랫폼으로부터 두 이벤트 모두를 유발하는 업데이트를 사용자 에이전트가 받았다면,
사용자 에이전트는 MUST 해당하는 pointermove보다 먼저
pointerrawupdate 이벤트를 디스패치해야 합니다.
target을 제외하면, 마지막 pointermove 이벤트 이후
디스패치된 모든 pointerrawupdate 이벤트들의
병합된 이벤트 목록을
이어 붙인 것은, 다음 pointermove 이벤트의 병합된
이벤트와(다른 이벤트 속성들의
관점에서) 동일합니다.
pointerrawupdate의 속성은
대부분 pointermove와 동일하지만,
cancelable만은 예외이며
pointerrawupdate에서는 MUST
false여야 합니다.
사용자 에이전트는 SHOULD
호환성 마우스 이벤트를
pointerrawupdate에 대해 발생시키지 말아야 합니다.
pointerrawupdate
이벤트에 대한 리스너를
추가하면, 사용자 에이전트의 구현에 따라 웹 페이지 성능에 부정적인 영향을 줄 수 있습니다.
대부분의 사용 사례에서는 다른 포인터 이벤트 유형들로 충분합니다.
JavaScript가 높은 빈도의 이벤트가 필요하고 그만큼 빠르게 처리할 수 있는 경우에만
pointerrawupdate
리스너를 추가해야 합니다.
이러한 경우에는 다른 유형의 포인터 이벤트를 들을 필요가 없을 가능성이 큽니다.
사용자 에이전트는 포인터가
활성 버튼 상태를 벗어나면 MUST 포인터 이벤트를 발생시켜
pointerup라는 이름의 이벤트를 발생시켜야 합니다. 마우스의 경우
이는 장치가 적어도 하나의 버튼이 눌린 상태에서 어떤 버튼도 눌리지 않은 상태로 전이될 때입니다. 터치의 경우 이는
디지타이저에서 물리적 접촉이 제거될 때입니다. 펜의 경우 이는 어떤 버튼도
눌리지 않은 상태에서 펜이 디지타이저와의 물리적 접촉에서 제거되거나, 호버 중에 적어도 하나의 버튼이 눌린 상태에서
어떤 버튼도 눌리지 않은 상태로 전이될 때입니다.
호버를 지원하지 않는 입력 장치의 경우,
사용자 에이전트는 또한
MUST 포인터 이벤트를 발생시켜
pointerout라는 이름의 이벤트를 발생시킨 다음,
포인터 이벤트 pointerleave를 발생시키고,
그 후에 pointerup 이벤트를 디스패치한 뒤에
수행해야 합니다.
모든 pointerup 이벤트는 pressure 값이
0입니다.
사용자 에이전트는 또한 포인터가 현재 캡처되어 있다면 MUST 암시적으로 포인터 캡처를 해제해야 합니다.
pointerdown 및 pointerup이 mousedown 및
mouseup과 동일한 모든 상황에서 발생되지 않음을 의미합니다. 자세한 내용은
코디드 버튼을 참고하세요.
사용자 에이전트는
포인터 이벤트 스트림을 억제하는 시나리오를 감지하면
MUST 포인터 이벤트를 발생시켜
pointercancel라는 이름의 이벤트를 발생시켜야 합니다.
pointercancel 이벤트의 다음 속성 값은, 동일한
pointerId를 가진 마지막으로 디스패치된 포인터
이벤트의 값과 일치해야 합니다(MUST): width, height,
pressure, tangentialPressure, tiltX, tiltY,
twist, altitudeAngle, azimuthAngle, pointerType,
isPrimary, 그리고 [UIEVENTS]로부터 상속된 좌표들입니다. 또한
pointercancel 이벤트의
coalescedEvents 및
predictedEvents 목록은 비어 있어야 하며(MUST), 이벤트의
cancelable
속성은 false여야 합니다(MUST).
사용자 에이전트는 MUST 다음 중 어느 하나라도 발생하면 포인터 이벤트를
발생시켜
pointerout라는 이름의 이벤트를 발생시켜야 합니다:
pointerup 이벤트를, 호버를 지원하지 않는 장치에 대해 사용자 에이전트가
발생시킨 후( pointerup 참조 ).사용자 에이전트는 MUST 다음 중 어느 하나라도 발생하면 포인터 이벤트를
발생시켜
pointerleave라는 이름의 이벤트를 발생시켜야 합니다:
pointerup 이벤트를, 호버를 지원하지 않는 장치에 대해 사용자 에이전트가
발생시킨 후( pointerup 참조 ).mouseleave 이벤트, 그리고
[CSS21]에
설명된
CSS :hover 의사 클래스와 유사한 점이 있습니다.
또한 pointerenter 이벤트도
참고하세요.
사용자 에이전트는 요소가 포인터
캡처를 받으면 MUST 포인터 이벤트를 발생시켜
gotpointercapture라는
이름의 이벤트를 발생시켜야 합니다. 이 이벤트는 포인터 캡처를 받는 요소에서 발생합니다. 이후 해당 포인터에 대한 이벤트는
이 요소에서 발생됩니다. 포인터 캡처 설정 및
대기 중인 포인터 캡처 처리 절을 참고하세요.
사용자 에이전트는 포인터에 대한
포인터 캡처가 해제된 후 MUST 포인터 이벤트를 발생시켜
lostpointercapture라는
이름의 이벤트를 발생시켜야 합니다. 이 이벤트는 캡처가 해제된 이후 해당 포인터에 대한 이후 이벤트들보다 먼저 발생되어야
합니다(MUST). 이 이벤트는 포인터 캡처가 제거된 요소에서 발생합니다. 이후 해당 포인터에
대한 모든 이벤트는( click,
auxclick, 및 contextmenu 이벤트는 예외) 이벤트 타깃을 결정하기 위해 일반적인
히트 테스트 메커니즘(이 명세의 범위를 벗어남)을 따릅니다. 포인터 캡처 해제,
포인터 캡처의 암시적 해제, 그리고
대기 중인 포인터 캡처 처리 절을 참고하세요.
사용자의 환경은 세로 스크롤을 y축을 따라 회전하는 것과, 가로 스크롤을 x축을 따라 회전하는 것과, 확대/축소를 z축을 따라 회전하는 것과 연관시키도록 구성될 수 있습니다.
WheelEvent 객체의 deltaX, deltaY, deltaZ 속성은
각 축을 따라 픽셀, 줄, 또는 페이지 단위로 측정된 값을 나타냅니다. 보고되는 측정값은
환경별 알고리즘이 휠 장치의 실제 회전/이동을 적절한 값과 단위로 변환한 뒤에 제공됩니다.
사용자의 환경 설정은 휠 장치의 실제 회전/이동을 서로 다른 방식으로 해석하도록 사용자화될 수 있습니다.
일반적인 톱니가 있는
마우스 휠의 한 번 움직임은 162 픽셀의 측정값을 생성할 수 있습니다
(162는 단지 예시 값이며, 실제 값은 사용자 에이전트의 현재 화면
크기에 따라 달라질 수 있습니다).
하지만 사용자는 기본 환경 설정을 변경하여 마우스 휠을 더 빠르게 하도록 할 수 있고,
그로 인해 이 숫자가 증가할 수 있습니다.
더 나아가, 일부 마우스 휠 소프트웨어는 가속(휠을 더 빠르게 회전/이동할수록 각 측정의
델타가 더 커짐) 또는
심지어 서브픽셀
회전
측정값을 지원할 수도 있습니다.
이 때문에 작성자는 어떤 사용자 에이전트에서의 특정
회전 양이
모든 사용자 에이전트에서 동일한
델타 값을 만들어 낼
것이라고 가정할 수 없습니다.
wheel 이벤트 사이에서 일관되어야 합니다(MUST).
사용자 에이전트가
wheel 이벤트의 기본 동작으로 스크롤을 수행한다면,
델타의 부호는
문서의 양의 X, Y, Z 축이 각각 오른쪽 끝, 아래쪽 끝, 그리고 가장 먼 깊이(사용자에게서 멀어지는 방향)를 향하는
오른손 좌표계에 의해 주어져야 합니다(SHOULD).
개별 사용자 에이전트는(환경 및 하드웨어 구성에 따라) 동일한 물리적 사용자 상호작용을 휠에서 서로 다르게 해석할 수 있습니다. 예를 들어, 트랙패드 가장자리에서 위에서 아래로 수행한 세로 스와이프는 페이지를 아래로 스크롤하려는 휠 동작으로 해석될 수도 있고 페이지를 위로 패닝하려는 동작으로 해석될 수도 있습니다(즉 각각 양수 또는 음수 deltaY 값이 결과로 나올 수 있습니다).
스크롤 가능한 요소에서 대상이 된 일련의 휠 이벤트가 어떤 자식 요소 위에서 시작되면, 동일한 사용자 제스처에 대한 이후 이벤트들은 그 자식 요소 위에서 발생할 수 있습니다.
WheelEvent 인터페이스는
wheel 이벤트와 연관된
특정 컨텍스트 정보를 제공합니다.
WheelEvent 인터페이스의 인스턴스를 생성하려면,
WheelEvent 생성자를 사용하고,
선택적 WheelEventInit 딕셔너리를 전달합니다.
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;
};
DOM_DELTA_PIXELDOM_DELTA_LINEDOM_DELTA_PAGEdeltaXwheel
이벤트의 기본 동작이 스크롤인 사용자 에이전트에서는, 이벤트가 취소되지 않은 경우 스크롤될
x축 방향의 측정값(픽셀, 줄, 또는 페이지 단위)이어야 합니다(MUST).
그렇지 않으면 이는 x축을 중심으로 한 휠 장치의 이동에 대한
구현별 측정값(픽셀, 줄, 또는 페이지 단위)입니다.
이 속성의 초기화되지
않은 값은 MUST
0.0이어야 합니다.
deltaYwheel
이벤트의 기본 동작이 스크롤인 사용자 에이전트에서는, 이벤트가 취소되지 않은 경우 스크롤될
y축 방향의 측정값(픽셀, 줄, 또는 페이지 단위)이어야 합니다(MUST).
그렇지 않으면 이는 y축을 중심으로 한 휠 장치의 이동에 대한
구현별 측정값(픽셀, 줄, 또는 페이지 단위)입니다.
이 속성의 초기화되지
않은 값은 MUST
0.0이어야 합니다.
deltaZwheel
이벤트의 기본 동작이 스크롤인 사용자 에이전트에서는, 이벤트가 취소되지 않은 경우 스크롤될
z축 방향의 측정값(픽셀, 줄, 또는 페이지 단위)이어야 합니다(MUST).
그렇지 않으면 이는 z축을 중심으로 한 휠 장치의 이동에 대한
구현별 측정값(픽셀, 줄, 또는 페이지 단위)입니다.
이 속성의 초기화되지
않은 값은 MUST
0.0이어야 합니다.
deltaModedeltaMode 속성은
델타
값들에 대한 측정 단위를 나타냅니다. 기본값은
DOM_DELTA_PIXEL(픽셀)입니다.
이 속성은 델타 값의 측정 단위를 나타내기 위해
DOM_DELTA 상수 중 하나로 설정되어야 합니다(MUST).
정확한 측정은 장치, 운영 체제, 애플리케이션 구성에 따라 다릅니다.
이 속성의 초기화되지
않은 값은 MUST
0이어야 합니다.
WebIDLdictionary WheelEventInit : MouseEventInit {
double deltaX = 0.0;
double deltaY = 0.0;
double deltaZ = 0.0;
unsigned long deltaMode = 0;
};
deltaXdeltaZ 속성을 참고하세요.deltaYdeltaZ 속성을 참고하세요.deltaZdeltaZ 속성을
WheelEvent 객체에서 초기화합니다.
이 속성(및
deltaX,
deltaY 속성)의 상대적인 양수 값은,
X, Y, Z 축이 각각 문서의 오른쪽 끝, 아래쪽 끝,
그리고 가장 먼 깊이(사용자에게서 멀어지는 방향)를 향하는 오른손 좌표계에 의해 주어집니다.
상대적인 음수 값은 각 축의 반대 방향입니다.
deltaMode
deltaMode 속성을
WheelEvent 객체에서 열거 값 0, 1 또는 2로
초기화합니다. 이는 휠의
회전이 스크롤을 유발했을 경우의 스크롤된 픽셀 수
(DOM_DELTA_PIXEL), 스크롤된 줄 수
(DOM_DELTA_LINE), 또는 스크롤된
페이지 수
(DOM_DELTA_PAGE)를
나타냅니다.
| Type | wheel |
|---|---|
| Interface | WheelEvent |
| Sync / Async | 비동기 |
| Bubbles | 예 |
| Trusted Targets | Element |
| Cancelable | 상황에 따라 다름 |
| Composed | 예 |
| Default action | 문서를 스크롤(또는 확대/축소) |
| Context (trusted events) |
|
wheel 이벤트로 전달될 수도 있고,
0이 아닌 각 축마다 별도의
wheel 이벤트로 전달될 수도 있습니다.
wheel 이벤트 유형의 일반적인
기본 동작은
표시된 양만큼 문서를 스크롤(또는 경우에 따라 확대/축소)하는 것입니다.
이 이벤트가 취소되면, 구현은 MUST NOT 문서를 스크롤하거나 확대/축소(또는 이 이벤트
유형과 연관된 다른 구현별 기본 동작을 수행)해서는 안 됩니다.
휠 이벤트에서 preventDefault를 호출하면 스크롤을 방지하거나
그 밖의 방식으로 스크롤을 중단시킬 수 있습니다.
최대의 스크롤 성능을 위해, 사용자 에이전트는 스크롤과 연관된 각 휠 이벤트가
취소될지 확인하기 위해 처리될 때까지 기다리지 않을 수도 있습니다.
이러한 경우 사용자 에이전트는 cancelable 속성이 false인
wheel 이벤트를 생성해야 하며, 이는
preventDefault를 사용하여 스크롤을 방지하거나 중단시킬 수 없음을 나타냅니다.
그렇지 않으면 cancelable은 true가 됩니다.
특히, 사용자 에이전트는 이벤트에 대해
비수동(non-passive) 리스너가 없음을
관찰할 때
오직 취소 불가능한 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 이벤트 유형에 해당합니다.
onpointerenterpointerenter 이벤트 유형에 해당합니다.
onpointerdownpointerdown 이벤트 유형에 해당합니다.
onpointermovepointermove 이벤트 유형에 해당합니다.
onpointerrawupdatepointerrawupdate 이벤트 유형에 해당합니다.
onpointeruppointerup 이벤트 유형에 해당합니다.
onpointercancelpointercancel 이벤트 유형에
해당합니다.
onpointeroutpointerout 이벤트 유형에 해당합니다.
onpointerleavepointerleave 이벤트 유형에
해당합니다.
ongotpointercapturegotpointercapture 이벤트 유형에 해당합니다.
onlostpointercapturelostpointercapture 이벤트 유형에 해당합니다.
속성 및 기본 동작에서 언급했듯이,
뷰포트 조작(패닝 및 확대/축소)은 포인터 이벤트를 취소하는 것만으로 억제할 수 없습니다. 대신 작성자는
touch-action CSS 속성을 사용하여, 이 동작들 중 어떤 것을 허용하고 어떤 것을 억제할지
선언적으로 정의해야 합니다.
touch-action CSS 속성은 터치 입력만을 참조하는 것처럼 보이지만,
실제로는 패닝 및 확대/축소를 위한 직접 조작을 허용하는 모든 형태의 포인터 입력에 적용됩니다.| Name: | touch-action |
|---|---|
| Value: | auto | none | [ [ pan-x | pan-left |
pan-right ] || [ pan-y | pan-up |
pan-down ] ] | manipulation
|
| Initial: | auto |
| Applies to: | 비대체 인라인 요소, 테이블 행, 행 그룹, 테이블 열, 및 열 그룹을 제외한 모든 요소 |
| Inherited: | 아니오 |
| Percentages: | N/A |
| Media: | 시각적 |
| Computed value: | 지정된 값과 동일 |
| Canonical order: | 문법에 따름 |
| Animation type: | 애니메이션 불가 |
touch-action CSS 속성은(속성의 이름과 달리 터치에만 제한되지 않는)
직접 조작 상호작용이
사용자 에이전트의 패닝 및 확대/축소 동작을 유발할 수 있는지 여부를 결정합니다(MAY).
touch-action 값 절을 참고하세요.
패닝 또는 확대/축소를 시작하기 직전에, 다음 조건이 모두 참이면 사용자 에이전트는 MUST 포인터 이벤트 스트림을 억제해야 합니다:
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으로 프로그램적으로 변경하더라도,
해당 포인터가 활성인 동안 사용자 에이전트가 그 입력에 대한 어떤 패닝 또는 확대/축소 동작도 중단하거나 억제하는
결과로 이어지지 않습니다.
touch-action의 다양한 pan-* 값들의 경우에도,
사용자 에이전트가 제스처 시작 시점에 그 제스처를 직접 처리할지 여부를 결정한 뒤에는,
동일한 제스처의 이후 방향 변경은 해당 포인터가 활성인 동안 사용자 에이전트에 의해 무시되어야 합니다(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>
이 요소에서의 직접 조작 상호작용은 부모를 조작하기 위해 소비될 수도 있습니다(MAY).
</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>
이 절은 규범적이지 않습니다.
포인터 캡처는 특정 포인터에 대한 이벤트(어떤 호환성 마우스 이벤트를 포함)를, 포인터 위치의
일반적인
히트 테스트
결과가 아닌 특정 요소로
다시 타기팅(retarget)할 수 있게 합니다.
이는 사용자 정의 슬라이더 컨트롤(예: [HTML]의
<input type="range"> 컨트롤과 유사) 같은 시나리오에서 유용합니다.
포인터 캡처는 슬라이더의 엄지(thumb) 요소에 설정될 수 있으며,
사용자는 포인터가 엄지에서 벗어나더라도 컨트롤을 앞뒤로 슬라이드할 수 있습니다.
pointerdown이 발생한 뒤,
포인터 캡처를 사용하면 포인터가 엄지에서 벗어나더라도 사용자가 엄지를 슬라이드할 수 있습니다.
포인터 캡처는 Element 타입의 element에 대해
element.setPointerCapture(pointerId) 메서드를 호출함으로써 설정됩니다.
이 메서드가 호출되면, 사용자 에이전트는 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에 대해,
설정되어 있다면 대기 중인 포인터 캡처 대상
오버라이드를
비웁니다.패닝 및 확대/축소를 위한 직접 조작 상호작용을 구현하는 입력(예: 터치스크린에서의 터치 또는 스타일러스)은,
어떤 setPointerCapture가
모든 pointerdown 리스너가 호출되기 직전에
대상 요소에서 호출된 것과 정확히 동일하게 동작해야 합니다(SHOULD).
hasPointerCapture API는(예:
pointerdown 리스너에서)
이것이 발생했는지 여부를 결정하는 데 사용될 수 있습니다.
다음 포인터 이벤트가 발생하기 전에 포인터에 대해
releasePointerCapture가 호출되지 않으면,
캡처가 활성 상태임을 나타내기 위해(정상적으로) 대상에
gotpointercapture 이벤트가 디스패치됩니다.
pointerup 또는 pointercancel 이벤트를 발생시킨 직후,
사용자 에이전트는 MUST
방금 디스패치된 pointerId에 대해,
대기 중인 포인터 캡처 대상 오버라이드를 비운 뒤,
필요하다면 lostpointercapture를
발생시키기 위해
대기 중인 포인터 캡처 처리 단계를 실행해야 합니다.
대기 중인 포인터 캡처 처리 단계를 실행한 후,
포인터가 호버를 지원한다면, 사용자 에이전트는
MUST
캡처가 없는 포인터의 현재 위치를 반영하는 데 필요한 해당 경계 이벤트도 전송해야 합니다.
포인터 캡처 대상 오버라이드가 더 이상 연결됨이 아니라면 [DOM], 포인터 캡처 대상 오버라이드는 문서로 설정되어야 합니다(SHOULD).
대기 중인 포인터 캡처 대상 오버라이드가 더 이상 연결됨이 아니라면 [DOM], 대기 중인 포인터 캡처 대상 오버라이드 노드는 비워져야 합니다(SHOULD).
lostpointercapture
이벤트가 문서에서 발생하게
만듭니다.
포인터 락 [PointerLock]이 요소에 성공적으로 적용되면,
사용자 에이전트는 MUST
어떤 요소가 캡처되었거나 캡처 대기 중인 상태라면,
releasePointerCapture 메서드가
호출된 것처럼 단계를 실행해야 합니다.
성능상의 이유로, 사용자 에이전트는 포인터의
측정 가능한 속성
(예: 좌표, 압력, 접선 압력, 기울기, 트위스트, 또는 접촉 기하)
이 갱신될 때마다
pointermove
이벤트를 보내지 않기로 선택할 수도 있습니다.
대신 여러 변경을 단일
pointermove 또는
pointerrawupdate 이벤트로
병합(결합/합치기)할 수 있습니다.
이 접근 방식은 사용자 에이전트가 수행해야
하는(MUST)
이벤트 처리량을 줄이는 데 도움을 주지만,
포인터 위치를 추적할 때의 세밀도와 충실도는 자연스럽게 감소하며,
특히 빠르고 큰 움직임에서 두드러집니다.
getCoalescedEvents 메서드를 사용하면,
애플리케이션은 병합되지 않은 원시 위치 변화에 접근할 수 있습니다.
이는 포인터 이동 데이터를 보다 정밀하게 처리할 수 있게 합니다.
예를 들어 드로잉 애플리케이션에서는, 병합되지 않은 이벤트를 사용하여 실제 포인터의 움직임에 더 가깝게
더 부드러운 곡선을 그릴 수 있습니다.
pointermove 이벤트의
병합된 좌표만 사용하면(회색 점), 곡선이 눈에 띄게 각지고 울퉁불퉁해집니다;
getCoalescedEvents()가 제공하는 더 세밀한 점(빨간 원)을 사용해 동일한 선을 그리면
포인터 이동에 대한 더 부드러운 근사치를 얻습니다.PointerEvent에는 연관된
병합된 이벤트
목록이 있으며
(0개 이상의 PointerEvent의 목록),
신뢰된(trusted)
pointermove 및
pointerrawupdate 이벤트에 대해,
이 목록은 이 이벤트로 병합된 모든 PointerEvent들의 시퀀스입니다.
"부모(parent)" 신뢰된
pointermove 및
pointerrawupdate 이벤트는
이러한 병합된 이벤트들의 누적을 나타내지만,
추가적인 처리(예: 디스플레이 리프레시 레이트에 맞추기)가 있을 수 있습니다.
그 결과, 이러한 이벤트들의 병합된 이벤트 목록은 항상 최소 1개의 이벤트를 포함합니다.
다른 모든 신뢰된 이벤트 유형에 대해서는 빈 목록입니다.
신뢰되지 않은(untrusted) 이벤트의
병합된 이벤트 목록은
생성자에 전달된 값으로 초기화됩니다.
isTrusted 비트를
false로 설정하지만,
병합된 이벤트 목록에 있는 이벤트들의 동일 비트는
원래의 true 값에서 변경되지 않습니다.
신뢰된 이벤트의 병합된 이벤트 목록에 있는 이벤트는 다음을 가집니다:
timeStamp 값
[DOM] —
모든 병합된 이벤트는, getPredictedEvents 메서드가 호출된
디스패치된 포인터 이벤트의
timeStamp보다 작거나 같은
timeStamp를 가집니다.
병합된 이벤트 목록은
timeStamp 기준으로
시간 순서대로 정렬되어야 하며(MUST),
첫 이벤트는 가장 작은
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>
이렇게 디스패치된 모든 이벤트의 순서는 원본 이벤트의 실제 순서와 일치해야 합니다(MUST).
예를 들어 pointerdown 이벤트가
병합된 pointermove 이벤트들의 디스패치를 유발하는 경우,
사용자 에이전트는 MUST
먼저 해당 pointerId의
모든 병합된 이벤트를 포함하는
pointermove 이벤트 1개를 디스패치하고,
그 뒤에 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 이벤트는 비어 있지 않은
병합된 이벤트 목록을 가질 수도 있지만,
성능상의 이유로
예측 이벤트 목록은 보통 빈 목록입니다.
목록에 포함되는 이벤트 수와 현재 타임스탬프로부터 얼마나 떨어져 있는지는 사용자 에이전트 및 사용되는 예측 알고리즘에 의해 결정됩니다.
신뢰된 이벤트의 예측 이벤트 목록에 있는 이벤트는 다음을 가집니다:
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):
현재 존재하는 웹 콘텐츠의 대다수는 마우스 이벤트만을 대상으로 코딩되어 있습니다. 아래에서는 이러한 콘텐츠와의 호환성을 위해 사용자 에이전트가 일반적인 포인터 입력을 마우스 이벤트로 매핑할 수 있는(MAY) 알고리즘을 설명합니다.
마우스 이벤트와의 호환성 매핑은 이 명세의 선택적(OPTIONAL) 기능입니다. 사용자 에이전트는 기존 레거시 콘텐츠와의 최상의 호환성을 위해 이 기능을 지원하도록 권장됩니다.
개략적으로, 호환성 마우스 이벤트는 해당 포인터 이벤트들과 "교차(interleaved)"되도록 의도됩니다. 하지만 이 구체적인 순서는 필수는 아니며, 호환성 마우스 이벤트를 구현한 사용자 에이전트는 상대적 순서가 일관되기만 하면(MAY) 마우스 이벤트의 디스패치를 지연시키거나 묶어서(group) 디스패치하기로 결정할 수 있습니다.
특히 터치스크린 입력의 경우, 사용자 에이전트는 제스처 인식을 위해 추가적인 휴리스틱을 적용할 수도 있습니다(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 이벤트를
발생시킬지 여부를 결정하기 위해 자체 휴리스틱을 적용할 수 있습니다.
일부 사용자 에이전트는 동일 타입의 다른(비-프라이머리) 포인터가 존재하거나,
다른 타입의 다른 프라이머리 포인터가 존재하면 이러한 이벤트를 발생시키지 않기로 선택할 수 있습니다.
사용자 에이전트는 특정 동작이 "깔끔한(clean)" 탭, 클릭, 또는 롱프레스가 아니라고(예: 터치스크린에서 손가락이
화면에 접촉한 상태에서 상호작용에 너무 많은 이동이 포함된 경우) 판단하고,
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 중 하나라도 설정 해제된 값이라면, 이를 창 밖(out-of-window) 마우스 위치로 간주합니다.
레거시 마우스 포인터의 유효 위치는,
포인터 전환 이벤트(pointerover, pointerout, pointerenter,
pointerleave)에서
대응하는 레거시 마우스 전환 이벤트(mouseover, mouseout,
mouseenter, mouseleave)로의
직접적인 매핑을 항상 가질 수는 없다는 사실을 모델링합니다.
아래 애니메이션은, 단일 레거시 마우스 입력을 사용하여 두 프라이머리 포인터를 조정(reconcile)하기 위해
사용자 에이전트가 포인터 전환 이벤트보다 더 많은 레거시 마우스 전환 이벤트를 디스패치해야 하는 경우를
보여줍니다.
이 애니메이션에서, 마우스 클릭과 터치 탭 사이의 시간 구간에 주목하세요.
버튼 1은 이 기간 동안 pointerout 이벤트를 받지 않습니다(왜냐하면 "실제" 마우스 포인터가 이 기간 동안
버튼 사각형을 떠나지 않았기 때문입니다).
하지만 버튼 1은, 터치 탭 시점에 레거시 마우스 포인터의
유효 위치가
버튼 2로 이동할 때 mouseout 이벤트를 받습니다.
마찬가지로 터치 탭과, 마우스가 버튼 1을 떠나기 직전의 순간 사이의 시간 구간에서도,
같은 이유로 버튼 1은 pointerover 이벤트를 받지 않지만,
레거시 마우스 포인터의 유효 위치가
버튼 1 내부로 다시 이동할 때 버튼 1은 mouseover 이벤트를 받습니다.
사용자 에이전트가 호버를 지원하는 장치에 대해 포인터 이벤트를 디스패치해야 할 때마다, SHOULD 다음 단계를 실행해야 합니다:
isPrimary 속성이 false라면,
포인터 이벤트를 디스패치하고 이 단계를 종료합니다.pointerdown,
pointerup 또는
pointermove 이벤트이거나,
window에서의
pointerleave 이벤트라면,
레거시 마우스 포인터의 유효
위치 추적에서
설명한 대로 호환성 마우스 전환 이벤트를 디스패치합니다.
pointerdown이고,
이벤트의 취소됨(canceled)
플래그가 설정되어 있다면,
이 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)
플래그가 설정되어 있다면,
이 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]에서 정의됨)와 포인터 이벤트를 모두 지원한다면, 사용자 에이전트는 MUST NOT 이 절에서 설명한 호환성 마우스 이벤트와, [TOUCH-EVENTS]에 개요로 제시된 대체(fallback) 마우스 이벤트를 둘 다 생성해서는 안 됩니다.
호버를 지원하지 않는 프라이머리 포인터(예: 터치스크린에서의
한 손가락)로 요소를 활성화(click)하는 경우, 일반적으로 다음 이벤트 시퀀스가 생성됩니다:
mousemovepointeroverpointerentermouseovermouseenterpointerdownmousedownpointermove 및
mousemove 이벤트
pointerupmouseuppointeroutpointerleavemouseoutmouseleaveclick하지만 이 상호작용 중에
pointerdown 이벤트의
취소됨(canceled) 플래그가
설정되면, 이벤트 시퀀스는 다음과 같습니다:
mousemovepointeroverpointerentermouseovermouseenterpointerdownpointermove 이벤트
pointeruppointeroutpointerleavemouseoutmouseleaveclick이 부록에서는 포인터 이벤트 구현에 대한 보안 및 개인정보 보호 고려사항을 다룹니다. 논의는 이 명세에서 정의한 이벤트 모델, API 및 이벤트의 구현으로부터 직접 발생하는 보안 및 개인정보 보호 문제로 제한됩니다.
이 명세에서 정의된 많은 이벤트 유형은 사용자 동작에 대한 응답으로 디스패치됩니다. 이는 악의적인 이벤트 리스너가 사용자가 일반적으로 기밀로 간주할 정보를 획득할 수 있게 합니다. 예를 들어, 사용자가 페이지와 상호작용하는 동안 사용자의 마우스/스타일러스/손가락의 정확한 경로/이동입니다.
포인터 이벤트에는(사용자의 장치에서 지원되는 경우) 펜 입력이 잡히는 각도나 기울기, 접촉 표면의 기하, 스타일러스 또는 터치스크린에 가해지는 압력과 같은 추가 정보가 포함됩니다. 각도, 기울기, 기하 및 압력에 대한 정보는 사용자의 장치에 있는 센서와 직접적으로 연관되어 있으므로, 이 명세는 오리진이 이러한 센서에 접근할 수 있도록 합니다.
이러한 센서 데이터와, 사용된 입력 메커니즘 유형(마우스, 터치, 펜)을 판별할 수 있는 능력은 사용자 또는 사용자의 장치와 환경의 특성을 추론하는 데 사용될 수 있습니다. 이러한 추론된 특성과 장치/환경 정보는 그 자체로 민감할 수 있습니다. 예를 들어, 악의적인 사이트가 사용자가 보조 기술을 사용하고 있는지 여부를 추가로 추론할 수 있게 할 수 있습니다. 이 정보는 또한 사용자 프로필을 구축하거나, 특정 사용자를 “지문 채집(fingerprint)”하여 추적하는 목적으로 잠재적으로 사용될 수 있습니다.
완화책으로, 사용자 에이전트는 사용자가 특정 센서 데이터(예: 각도, 기울기, 압력)에 대한 접근을 비활성화할 수 있는 기능을 포함하는 것을 고려할 수 있으며, 그리고/또는 사용자로부터의 명시적 옵트인 이후에만 이를 사용할 수 있게 하는 것을 고려할 수 있습니다.
이 명세는 작성자가 “예측 이벤트(predicted events)”에 접근할 수 있는 방법을 정의합니다. 하지만 이 명세 자체는 사용자 에이전트가 예측에 사용해야 하는 알고리즘을 정의하지 않습니다. 명세 작성자는 알고리즘이 사용자가 수행 중인 현재 제스처와 관련된 선행 포인터 이벤트에만 의존하도록 예상합니다. 사용자 에이전트는 예측 알고리즘의 구체적인 구현이 다른 사이트에 걸친 사용자의 전체 상호작용 이력 같은 추가 데이터에 의존하지 않도록 보장할 책임이 있으며, 그러한 데이터는 사용자에 대한 민감한 정보를 드러내거나 사용자를 “지문 채집(fingerprint)”하여 추적하는 데 사용될 수 있습니다.
이러한 고려사항을 넘어, 작업 그룹은 이 명세가 다음을 만족한다고 믿습니다:
이 절은 규범적이지 않습니다.
buttons 속성이 0이 아닌 값을 가지는 상태입니다. 마우스의 경우 장치에서 최소 1개의 버튼이
눌려 있는 상태입니다. 터치의 경우 디지타이저와 물리적으로 접촉한 상태입니다. 펜의 경우 펜이 디지타이저와
물리적으로 접촉했거나, 또는 호버 중 최소 1개의 버튼이 눌려 있는 상태입니다.pointerId로
식별됨)가 문서 내에서 추가 이벤트를 생성할 수 있다면, 그 포인터는 여전히 활성으로 간주됩니다. 예시:
WheelEvent 인터페이스를 지원하는 입력 장치(예: 마우스 휠 또는
터치 패드)의 물리적 움직임에 응답하여, 사용자 에이전트가 페이지를 스크롤하거나 확대/축소할 것으로 예상되는
스크롤 양(픽셀, 줄, 또는 페이지 단위)입니다. 델타 값(예: deltaX, deltaY, 또는 deltaZ 속성)은 현재
deltaMode 속성의 컨텍스트에서
해석되어야 합니다. 휠(또는 다른 장치)의 물리적 움직임과
델타가 양수인지
음수인지의 관계는 환경 및 장치에 따라 달라집니다. 그러나 사용자 에이전트가
기본 동작으로 스크롤한다면,
델타의 부호는,
양의 X, Y, Z 축이 각각 문서의 가장
오른쪽 가장자리,
가장 아래 가장자리, 그리고 가장 먼 깊이(사용자에게서 멀어지는 방향)를 향하는 오른손 좌표계에 의해 주어집니다.
측정 가능한 속성은 실수 또는 큰 도메인의 정수로 표현되는 연속적인 포인터 센서 데이터와 관련된 값들을
나타냅니다. 포인터 이벤트에서 width, height,
pressure, tangentialPressure, tiltX, tiltY,
twist, altitudeAngle, azimuthAngle, 그리고
[UIEVENTS]의
마우스 이벤트 모델 속성 screenX, screenY, clientX,
clientY는 측정 가능한 속성입니다.
반면 pointerId, pointerType,
isPrimary, 그리고 [UIEVENTS]의 마우스 이벤트 모델 속성 button,
buttons, ctrlKey, shiftKey, altKey,
metaKey는 센서 데이터와 관련되지 않으므로 측정 가능한 속성으로 간주되지 않습니다.
WheelEvent 인터페이스를 사용하는 입력 장치에서의 증분 변화의
표시입니다. 일부 장치에서는 이것이 휠의 문자 그대로의 회전일 수도 있지만(MAY),
다른 장치에서는 평평한 표면을 따라 움직이거나 특정 버튼에 압력을 가하는 것일 수도 있습니다(MAY).히트 테스트기능은 대상을 결정하는 데 사용됩니다. 히트 테스트 및 쌓임(stacking) 순서에 대한 구체적인 세부 사항은 호스트 언어를 참고하세요.
이 절은 규범적입니다. 다음 기능들은 폐기(obsolete)되었으며, 레거시 소프트웨어와의 호환성이 필요한 사용자 에이전트만 구현해야 합니다. 또한 [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 Draft 전체 개정 이력을 참고하세요.
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;
};
dictionary WheelEventInit : MouseEventInit {
double deltaX = 0.0;
double deltaY = 0.0;
double deltaZ = 0.0;
unsigned long deltaMode = 0;
};
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: