現行標準の公開以降に報告されたエラーや問題については、正誤表を必ずご確認ください。
Copyright © 2019 W3C® (MIT, ERCIM, Keio, Beihang). W3C liability, trademark and permissive document license rules apply.
この仕様書の機能は、マウス、ペン、タッチスクリーンなどのデバイスから、ハードウェア非依存のポインター入力を扱うイベントと関連インターフェイスを記述した、W3C勧告「Pointer Events」に含まれる機能を拡張または修正します。既存のマウスベースのコンテンツとの互換性を保つため、この仕様では他のポインターデバイスタイプにもMouse Eventsを発火するためのマッピングについても説明します。
このセクションでは、本書が公開された時点のステータスについて説明します。他の文書が本書に取って代わる場合があります。現行標準のW3C公開文書一覧や、この技術レポートの最新改訂版は、W3C技術レポート索引(https://www.w3.org/TR/)でご覧いただけます。
この文書は、Pointer Eventsワーキンググループによって勧告として公開されました。 実装報告は相互運用性を実証しています。 この文書は [PointerEvents1] を置き換えます。
本仕様は [PointerEvents1] のアップデート版です。PointerEvents1は主にMicrosoft Internet ExplorerおよびMicrosoft Edgeで広く実装されていましたが、Pointer Events仕様がW3C勧告として公開された際、Mozilla Firefoxのプレリリース版にも独立したほぼ相互運用可能な実装が存在していました。レベル2では編集上の明確化、新機能、設計の一部側面について指摘された制限や懸念に対応するための軽微な破壊的変更が含まれており、より広範なブラウザーによる採用が可能となるよう努めています。
前回の公開以降、変更はありません。
この仕様に関する議論は、GitHub Issuesで行うことを推奨します。 または、メーリングリストへコメントを送信することも可能です。 送信先は public-pointer-events@w3.org (アーカイブ)。
この文書はW3Cメンバー、ソフトウェア開発者、その他のW3Cグループおよび関心のある関係者によってレビューされ、W3Cディレクターにより勧告として承認されています。これは安定した文書であり、参考資料として利用したり、他の文書から引用することができます。W3Cが勧告を作成する役割は、この仕様への関心を集め、広く展開を促進することです。これによりWebの機能性と相互運用性が向上します。
この文書は W3C 特許ポリシーのもとで運営されるグループによって作成されました。 W3Cは 関連する特許開示の公開リスト を管理しています。 このリストにはグループの成果物に関連して行われた特許開示と、 特許を開示するための手順も記載されています。個人が、 特許について実際に知識があり、その特許が 必須クレーム を含むと考える場合は、 W3C特許ポリシー第6節に従い情報を開示する必要があります。
この文書は 2019年3月1日 W3Cプロセス文書に準拠しています。
このセクションは規範的ではありません。
現在、ほとんどの[HTML5]コンテンツは、マウス入力で利用されたり、設計されたりしています。カスタムな方法で入力を処理するものは、一般的に[UIEVENTS]のMouse Eventsを利用してコーディングされます。しかし、今日の新しいコンピューティングデバイスは、タッチスクリーンやペン入力など、他の入力方式も取り入れています。これらの入力方式ごとに個別に処理するためのイベント型も提案されていますが、そのアプローチでは新しい入力タイプへの対応時に、ロジックやイベント処理の重複が発生しやすく、不要なコストがかかります。このことは、コンテンツが一つのデバイスタイプのみを想定して書かれた場合、互換性の問題を生みがちです。さらに、既存のマウスベースのコンテンツとの互換性のため、多くのユーザーエージェントは全ての入力タイプに対してMouse Eventsを発火します。これにより、Mouse Eventが実際のマウスデバイス由来なのか、互換性のために他の入力タイプから生成されたものなのかが曖昧になり、両方のデバイスタイプに同時に対応したコーディングが難しくなります。
複数の入力タイプへのコーディングコストを減らし、上記のMouse Eventsの曖昧さを解消するために、本仕様はより抽象的な入力方式「ポインター」を定義します。ポインターは、マウスカーソル、ペン、タッチ(マルチタッチを含む)、その他のポインティング入力デバイスによる画面上の任意の接触点を表します。このモデルにより、ユーザーがどんなハードウェアを持っていても正しく動作するサイトやアプリケーションが容易に作成できます。デバイス固有の処理が必要な場合には、イベントを発生させたデバイスタイプを判定するためのプロパティも定義しています。主な目的は、クロスデバイスのポインター入力に対して著者が容易にコーディングできる一組のイベントとインターフェイスを提供し、必要な場合にはデバイス固有の処理も拡張できるようにすることです。
もう一つの重要な目的は、マルチスレッドのユーザーエージェントがスクロールなどのデフォルトのタッチアクションを、スクリプト実行によるブロックなしに処理できるようにすることです。
この仕様は様々なポインター入力に対する統一されたイベントモデルを定義していますが、キーボードやキーボードに類似したインターフェイス(例えば、タッチスクリーンのみのデバイス上で動作するスクリーンリーダー等、フォーカス可能なコントロールや要素を順番にナビゲートできる支援技術)など、他の入力形式は対象外です。ユーザーエージェントがこれらのインターフェイスに応じてポインターイベントを生成する選択をする場合もありますが、このシナリオは本仕様の範囲外です。
まずは、著者はfocus
、blur
、click
などの高レベルイベントに応答することで、全ての入力形式に等価な機能を提供することが推奨されます。しかし、Pointer
Eventsなどの低レベルイベントを利用する場合、全ての入力タイプをサポートするように配慮してください。キーボードやキーボードに類似したインターフェイスの場合は、明示的なキーボードイベント処理の追加が必要です。詳細についてはWCAG 2.0 ガイドライン 2.1を参照してください。
汎用ポインター入力を扱うイベントは、マウス用のイベント(pointerdown、pointermove、pointerup、pointerover、pointeroutなど)とよく似ています。これにより、Mouse EventsからPointer Eventsへのコンテンツ移行が容易になります。 Pointer Eventsは、Mouse Eventsが持つ通常のプロパティ(クライアント座標、ターゲット要素、ボタン状態など)に加えて、他の入力形式向けの新しいプロパティ(圧力、接触形状、傾きなど)も提供します。著者はPointer Eventsを利用することで、異なる入力タイプ間でロジックを共有しやすくし、必要な場合のみ特定の入力タイプ向けにカスタマイズして最良の体験を実現できます。
Pointer Eventsは様々な入力デバイスから発生しますが、他のデバイス固有イベントから生成されるとは定義されていません。互換性のために推奨される場合もありますが、本仕様では他のデバイス固有イベント(マウスイベント、タッチイベント等)のサポート自体は必須ではありません。ユーザーエージェントはPointer Eventsだけをサポートし、他のデバイスイベントをサポートしないことも可能です。マウス固有イベントに基づいて書かれたコンテンツとの互換性のため、この仕様ではマウス以外のデバイスからのポインター入力に基づいて互換性マウスイベントを生成する方法について、任意のセクションも提供しています。
この仕様は、[TOUCH-EVENTS]で定義されるTouch EventsとPointer Eventsの両方をサポートするユーザーエージェントの期待動作については、特に助言していません。これら2つの仕様の関係については、Touch Events Community Groupを参照してください。
非規範と記載されたセクションだけでなく、本仕様書内の著作ガイドライン、図、例、および注記もすべて非規範です。 それ以外の本仕様書の内容は規範です。
重要な語句 MAY(許可)、MUST(必須)、MUST NOT(禁止)、OPTIONAL(任意)、SHOULD(推奨)、および SHOULD NOT(非推奨)は [RFC2119] に従って解釈されます。
このセクションは非規範です。
以下は、本仕様書のAPIの利用例となる著者コード例です。
/* Pointer Events または従来のタッチ/マウスにバインド */
if (window.PointerEvent) {
// Pointer Eventsがサポートされていれば、pointerイベントだけを監視
target.addEventListener("pointerdown", function(e) {
// 必要に応じてe.pointerTypeでタッチ/ペン/マウスの個別挙動を判別
// 各入力方式ごとの処理
...
});
...
} else {
// 従来のタッチ/マウスイベントハンドラ
target.addEventListener('touchstart', function(e) {
// 互換性マウスイベントやクリックの抑制
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固有のカスタムタイプ */
}
}
<style>
/* UAによるタッチの既定動作(パンやズームなど)を無効化し、
canvas要素上のすべてのイベントがアプリ側で処理されるようにする */
canvas { touch-action: none; }
</style>
<canvas id="drawSurface" width="500px" height="500px" style="border:1px solid black;"></canvas>
<script>
var canvas = document.getElementById("drawSurface"),
context = canvas.getContext("2d");
if (window.PointerEvent) {
canvas.addEventListener("pointermove", paint);
if(window.navigator.maxTouchPoints>1)
// UAとハードウェアがマルチタッチをサポート
...
} else {
// Pointer Events非対応UA向けのフォールバック
canvas.addEventListener("mousemove", paint);
}
function paint(event) {
if(event.buttons>0)
context.fillRect(event.clientX, event.clientY, 5, 5);
}
// キーボード操作用の追加イベント/関数
...
</script>
<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>
var event = new PointerEvent("pointerover",
{ bubbles: true,
cancelable: true,
composed: true,
pointerId: 42,
pointerType: "pen",
clientX: 300,
clientY: 500
});
eventTarget.dispatchEvent(event);
このセクションは非規範です。
buttons
プロパティが0以外の値を持つ場合の状態。マウスの場合は、少なくとも1つのボタンが押されているとき。タッチの場合は、デジタイザに物理的な接触があるとき。ペンの場合は、ペンがデジタイザに物理的に接触している、またはホバー中に少なくとも1つのボタンが押されているとき。
pointerId
で識別)がドキュメント内で追加のイベントを発生させる可能性がある場合、そのポインターはまだアクティブとみなされます。例:
preventDefault()
の使用、イベントハンドラでfalse
を返す、その他[UIEVENTS]や[HTML5]で定義される手段によって、デフォルト動作が防止されたイベント。
PointerEvent
インターフェイスdictionaryPointerEventInit
: MouseEventInit { long pointerId = 0; double width = 1; double height = 1; float pressure = 0; float tangentialPressure = 0; long tiltX = 0; long tiltY = 0; long twist = 0; DOMString pointerType = ""; boolean isPrimary = false; }; [Constructor(DOMString type, optionalPointerEventInit
eventInitDict), Exposed=Window] interfacePointerEvent
: MouseEvent { readonly attribute longpointerId
; readonly attribute doublewidth
; readonly attribute doubleheight
; readonly attribute floatpressure
; readonly attribute floattangentialPressure
; readonly attribute longtiltX
; readonly attribute longtiltY
; readonly attribute longtwist
; readonly attribute DOMStringpointerType
; readonly attribute booleanisPrimary
; };
pointerId
イベントを発生させたポインターの一意な識別子。この識別子は、[HTML5]で定義されるトップレベル閲覧コンテキスト内の他のアクティブポインターすべてと一意である必要があります。必要に応じて、ユーザーエージェントは以前に退役したアクティブポインターのpointerId
値を再利用してもかまいません。
pointerId
の選択アルゴリズムは実装依存です。そのため、著者は値が識別子以外の特別な意味を持つとは想定しないでください。例として、ユーザーエージェントはアクティブになった順番に1
から番号を割り当てることもできますが、これらの値が単調増加する保証はありません。他のユーザーエージェントは、各アクティブポインターに完全にランダムで一意な番号を割り当てる場合もあります。ただし、後者の場合、ユーザーエージェントは現在のページの存続期間中のみ同じpointerId
を割り当て、新しいpointerId
値が予測不可能であること(例:暗号学的に強い乱数で生成)を保証し、異なるページ間でユーザーが一意にフィンガープリント・追跡される可能性を最小限にする必要があります。
width
ポインターの接触ジオメトリの幅(X軸方向の大きさ)、CSSピクセル単位([CSS21]参照)。この値は、ポインターごとにイベント毎で更新されてもかまいません。通常、接触ジオメトリを持たない入力(従来のマウスなど)やハードウェアで実際の形状が検出できない場合、ユーザーエージェントはデフォルト値1を返す必要があります。
height
ポインターの接触ジオメトリの高さ(Y軸方向の大きさ)、CSSピクセル単位([CSS21]参照)。この値は、ポインターごとにイベント毎で更新されてもかまいません。通常、接触ジオメトリを持たない入力(従来のマウスなど)やハードウェアで実際の形状が検出できない場合、ユーザーエージェントはデフォルト値1を返す必要があります。
pressure
ポインター入力の正規化された圧力値(範囲[0,1]、0が最小・1が最大)。ハードウェアやプラットフォームが圧力をサポートしない場合は、アクティブボタン状態で0.5、非アクティブ時は0でなければなりません。注:すべてのpointerup
イベントは圧力0となります。
tangentialPressure
ポインター入力の正規化された接線圧(バレル圧・エアブラシスタイラスの指ホイールなどで設定)、範囲[-1,1](0がニュートラル)。一部ハードウェアは正の範囲[0,1]のみ対応。ハードウェアやプラットフォームが接線圧をサポートしない場合は、値は0でなければなりません。
tiltX
Y-Z平面と、トランスデューサ(ペンスタイラスなど)の軸とY軸を含む平面との間の平面角度(度数、範囲[-90,90])。正のtiltX
は右方向。tiltX
とtiltY
を組み合わせることで、トランスデューサがデジタイザの法線からどれだけ傾いているかを表現できます。ハードウェアやプラットフォームが傾きを報告しない場合は、値は0でなければなりません。
tiltX
。tiltY
X-Z平面と、トランスデューサ(ペンスタイラスなど)の軸とX軸を含む平面との間の平面角度(度数、範囲[-90,90])。正のtiltY
はユーザー方向。tiltY
とtiltX
を組み合わせることで、トランスデューサがデジタイザの法線からどれだけ傾いているかを表現できます。ハードウェアやプラットフォームが傾きを報告しない場合は、値は0でなければなりません。
tiltY
。twist
トランスデューサ(ペンスタイラスなど)が自身の主軸周りに時計回りに回転した度数(範囲[0,359])。ハードウェアやプラットフォームがツイストを報告しない場合は、値は0でなければなりません。
pointerType
イベントを発生させたデバイスタイプ(マウス、ペン、タッチなど)を示します。ユーザーエージェントがマウス、ペンスタイラス、またはタッチ入力デバイス用のポインターイベントを発火する場合、pointerType
の値は以下の表の通りでなければなりません:
ポインターデバイスタイプ | pointerType 値 |
---|---|
マウス | mouse |
ペンスタイラス | pen |
タッチ接点 | touch |
ユーザーエージェントがデバイスタイプを検出できない場合は、値は空文字列でなければなりません。上記以外のポインターデバイスタイプをサポートする場合、pointerType
の値はベンダープレフィックス付きとし、異なるデバイス間での名称衝突を避けるべきです。今後の仕様で他のデバイスタイプ向けの追加規範値が定義される可能性があります。
pointerType
の利用例については例2を参照してください。また、開発者はユーザーエージェントが独自のpointerType
値を実装している場合や、単に空文字列の場合に備えて、何らかのデフォルト処理を用意すべきです。
isPrimary
このポインターがこのポインタータイプのプライマリポインターかどうかを示します。
PointerEventInit
辞書は、PointerEvent
インターフェイスのコンストラクターで、信頼されていない(合成)ポインターイベントを構築するための仕組みを提供します。これは[UIEVENTS]で定義されるMouseEventInit
辞書を継承します。イベントの構築手順は[DOM4]で定義されています。信頼されていないポインターイベントの発火例については例を参照してください。
マルチポインター(例:マルチタッチ)シナリオでは、isPrimary
プロパティを使って各ポインタータイプのアクティブポインターの集合の中でマスターポインターを識別します。
pointerType
ごとにプライマリとみなされるポインターが存在します。例えば、タッチ接点とマウスカーソルが同時に動いた場合、それぞれがプライマリポインターとみなされます。
isPrimary
がfalse
でポインターイベントが発火される場合があります。
PointerEvent
インターフェイスによるイベントの発火eという名前のポインターイベントを発火するとは、[DOM4]で定義されるeという名前のイベントを発火することであり、そのイベントはPointerEvent
インターフェイスを使い、属性はPointerEvent
インターフェイスおよび属性とデフォルト動作に従ってセットされます。
イベントがgotpointercapture
またはlostpointercapture
でない場合、このPointerEvent
に対して保留中のポインターキャプチャの処理手順を実行します。
イベント発火対象オブジェクトは以下の通り決定されます:
このイベントがpointerdown
で、関連デバイスがダイレクトマニピュレーションデバイスかつ対象がElement
であれば、ポインターキャプチャの設定(pointerId
を対象要素に設定)を暗黙のポインターキャプチャとして行います。
決定された対象にイベントを発火します。
本仕様で定義されるイベントタイプのbubbles
・cancelable
プロパティおよびデフォルト動作は下表の通りです。各イベントタイプの詳細はポインターイベント型で説明します。
イベントタイプ | Bubbles | Cancelable | デフォルト動作 |
---|---|---|---|
pointerover |
Yes | Yes | なし |
pointerenter |
No | No | なし |
pointerdown |
Yes | Yes | 状況による:ポインターがプライマリの場合、mousedown イベントのデフォルト動作すべてこのイベントをキャンセルすると pointerType ごとにPREVENT MOUSE EVENT フラグがセットされ、以降特定の互換性マウスイベントの発火を防ぎます。
|
pointermove |
Yes | Yes | 状況による:ポインターがプライマリの場合、mousemove のデフォルト動作すべて |
pointerup |
Yes | Yes | 状況による:ポインターがプライマリの場合、mouseup のデフォルト動作すべて |
pointercancel |
Yes | No | なし |
pointerout |
Yes | Yes | なし |
pointerleave |
No | No | なし |
gotpointercapture |
Yes | No | なし |
lostpointercapture |
Yes | No | なし |
上記のうちpointerenter
とpointerleave
を除くすべてのポインターイベントのcomposed
([DOM4])属性はtrueであるべきです。
また、上記すべてのポインターイベントのdetail
([UIEVENTS])属性は0であるべきです。
fromElement
やtoElement
を公開しています。これらのユーザーエージェントでは、PointerEventで継承されるそれらの属性値はnull
にし、標準化された代替(target
やrelatedTarget
)の利用を促すべきです。
MouseEvents
[UIEVENTS]と同様に
relatedTarget
は、ポインターが離れた(pointerover
やpointerenter
の場合)要素、またはポインターが入った(pointerout
やpointerleave
の場合)要素に初期化されるべきです。他のポインターイベントでは、値はnullになります。なお、要素がポインターキャプチャを取得すると、以降のそのポインターの全イベントはキャプチャ要素の境界内とみなされます。
gotpointercapture
およびlostpointercapture
については、上表で定義された属性以外は、ユーザーエージェントが保留中のポインターキャプチャの処理を実行し、gotpointercapture
やlostpointercapture
イベントを発火した原因となったPointer
Eventと同じであるべきです。
ユーザーエージェントは、暗黙のポインターキャプチャ解除時およびgotpointercapture
やlostpointercapture
以外のPointer
Eventsを発火する際に、以下の手順を実行しなければなりません。
lostpointercapture
という名前のポインターイベントを発火する。gotpointercapture
という名前のポインターイベントを発火する。以下は本仕様で定義されるイベント型です。
プライマリポインターの場合、これらのイベント(gotpointercapture
とlostpointercapture
を除く)は互換性マウスイベントも発火する場合があります。
pointerover
イベントユーザーエージェントは、ポインティングデバイスが要素のヒットテスト境界内に移動したとき、pointerover
という名前のポインターイベントを発火しなければなりません。setPointerCapture
やreleasePointerCapture
でヒットテスト対象が変わる場合があり、キャプチャ中は境界イベント発火の目的上、常にキャプチャ要素の境界内にいるとみなされます。ホバー非対応デバイスの場合、pointerdown
イベント発火前にもこのイベントを発火しなければなりません(pointerdown
参照)。
pointerenter
イベントユーザーエージェントは、ポインティングデバイスが要素またはその子孫のヒットテスト境界内に移動したとき、pointerenter
という名前のポインターイベントを発火しなければなりません(pointerdown
イベントによる場合も含む、ホバー非対応デバイス参照)。setPointerCapture
やreleasePointerCapture
でヒットテスト対象が変わる場合があり、キャプチャ中は境界イベント発火の目的上、常にキャプチャ要素の境界内にいるとみなされます。このイベント型はpointerover
と似ていますが、バブリングしない点が異なります。
pointerdown
イベントユーザーエージェントは、ポインターがアクティブボタン状態になったとき、pointerdown
という名前のポインターイベントを発火しなければなりません。マウスの場合は、ボタンが未押下から1つ以上押下されたとき。タッチの場合は、デジタイザへの物理的接触時。ペンの場合は、ペンがボタン未押下状態でデジタイザに物理接触したとき、またはホバー中にボタン未押下から1つ以上押下されたとき。
pointerdown
やpointerup
はmousedown
やmouseup
と同じ状況すべてで発火するわけではありません。詳細は複数ボタン同時操作を参照。ホバー非対応デバイスの場合、ユーザーエージェントはpointerdown
イベント発火前にpointerover
とpointerenter
イベントも発火しなければなりません。
isPrimary
プロパティがtrue
の場合、pointerdown
イベントをキャンセルすることで、特定の互換性マウスイベントの発火を防ぐことができます。これによりポインターにPREVENT MOUSE EVENT
フラグがセットされます。ただし、mouseover
、mouseenter
、mouseout
、mouseleave
イベントの発火は防げません。
pointermove
イベントユーザーエージェントは、ポインターの座標が変化したときpointermove
という名前のポインターイベントを発火しなければなりません。また、ボタン状態、圧力、接線圧、傾き、ツイスト、接触ジオメトリ(例:width
やheight
)が変化し、他のポインターイベントの発火要件に該当しない場合にもpointermove
イベントを発火しなければなりません。
pointerup
イベントユーザーエージェントは、ポインターがアクティブボタン状態を離れたとき、pointerup
という名前のポインターイベントを発火しなければなりません。マウスの場合は、ボタンが1つ以上押下から全て未押下に遷移したとき。タッチの場合は、デジタイザから物理的接触がなくなったとき。ペンの場合は、ボタン未押下状態でデジタイザとの物理接触が解除されたとき、またはホバー中に1つ以上押下から全て未押下に遷移したとき。
ホバー非対応デバイスの場合、pointerup
イベント発火後にpointerout
とpointerleave
イベントも発火しなければなりません。
pointerdown
やpointerup
はmousedown
やmouseup
と同じ状況すべてで発火するわけではありません。詳細は複数ボタン同時操作を参照。pointercancel
イベントユーザーエージェントは以下の状況でpointercancel
という名前のポインターイベントを発火しなければなりません:
pointerdown
イベント発火後に、そのポインターがページビューポートの操作(パンやズーム)に使われた場合。
dragstart
イベントでpreventDefault
を呼ぶ)で防がれた場合、pointercancel
イベントは発火されません。
pointercancel
イベント発火後、ユーザーエージェントはpointerout
とpointerleave
イベントも発火しなければなりません。
このセクションは非規範です。
ユーザーエージェントがポインターが今後イベントを発生させる可能性が低いと判断するシナリオ例:
デバイスの画面向き変更、誤操作検知、ポインターによるビューポート操作(パンやズーム)方法は本仕様の範囲外です。
pointerout
イベントユーザーエージェントは以下のいずれかの場合にpointerout
という名前のポインターイベントを発火しなければなりません:
setPointerCapture
やreleasePointerCapture
でヒットテスト対象が変わる場合があり、キャプチャ中は境界イベント発火の目的上、常にキャプチャ要素の境界内にいるとみなされます。
pointerup
イベント発火後(pointerup
参照)。
pointercancel
イベント発火後(pointercancel
参照)。
pointerleave
イベントユーザーエージェントは、ポインティングデバイスが要素およびその子孫すべてのヒットテスト境界外に移動した場合、またはホバー非対応デバイスでpointerup
およびpointercancel
イベント発火後(pointerup
・pointercancel
参照)、pointerleave
という名前のポインターイベントを発火しなければなりません。setPointerCapture
やreleasePointerCapture
でヒットテスト対象が変わる場合があり、キャプチャ中は境界イベント発火の目的上、常にキャプチャ要素の境界内にいるとみなされます。ペンスタイラスがデジタイザで検知可能なホバー範囲外に離れた場合も発火しなければなりません。このイベント型はpointerout
と似ていますが、バブリングしない・ポインティングデバイスが要素および全子孫の境界外に完全に出るまで発火しない点が異なります。
gotpointercapture
イベント要素がポインターキャプチャを取得したとき、ユーザーエージェントはgotpointercapture
という名前のポインターイベントを発火しなければなりません。このイベントはキャプチャを受け取る要素で発火され、以降そのポインターのイベントはこの要素で発火されます。詳細はポインターキャプチャの設定および保留中のポインターキャプチャの処理参照。
lostpointercapture
イベントポインターキャプチャが解除された後、ユーザーエージェントはlostpointercapture
という名前のポインターイベントを発火しなければなりません。このイベントはキャプチャが解除された要素で発火され、以降そのポインターのイベントは通常のヒットテスト機構(本仕様の範囲外)でターゲットが決定されます。詳細はポインターキャプチャの解除、暗黙のポインターキャプチャ解除、保留中のポインターキャプチャの処理参照。
Element
インターフェイスの拡張以下のセクションでは、[HTML5]で定義されている既存のElement
インターフェイスを拡張し、ポインターキャプチャの設定と解除を容易にする方法を説明します。
partial interface Element
{
void setPointerCapture
(long pointerId);
void releasePointerCapture
(long pointerId);
boolean hasPointerCapture
(long pointerId);
};
setPointerCapture
このメソッドを呼び出した要素に対し、引数pointerId
で識別されるポインターのポインターキャプチャを設定します。以降、そのポインターのイベントは通常のヒットテスト結果の代わりにキャプチャ対象要素で発火され、ポインターがキャプチャ解除されるまで常にこの要素がターゲットとなります。このメソッドが有効になるには、ポインターがアクティブボタン状態である必要があります。そうでなければ静かに失敗します。引数がいずれのアクティブポインターにも一致しない場合、NotFoundError
という名前のDOMException
がスローされます。
releasePointerCapture
このメソッドを呼び出した要素から、引数pointerId
で識別されるポインターのポインターキャプチャを解除します。以降、そのポインターのイベントは通常のヒットテスト機構(本仕様の範囲外)に従ってターゲットが決定されます。引数がいずれのアクティブポインターにも一致しない場合、NotFoundError
という名前のDOMException
がスローされます。
hasPointerCapture
このメソッドを呼び出した要素が、引数pointerId
で識別されるポインターに対してポインターキャプチャを持つかどうかを示します。特に、pointerId
のpending pointer capture target
overrideがこの要素に設定されていればtrue
、そうでなければfalse
となります。
setPointerCapture
を呼び出した直後にtrue
を返しますが、その要素がまだgotpointercaptureイベントを受け取っていない場合でも同様です。そのため、暗黙のポインターキャプチャをpointerdownイベントリスナー内から検出するのに有用です。GlobalEventHandlers
mixinの拡張
以下のセクションでは、[HTML5]で定義されている既存のGlobalEventHandlers
mixinの拡張について説明し、イベントハンドラの登録を容易にします。
partial interface mixin GlobalEventHandlers
{
attribute EventHandler ongotpointercapture
;
attribute EventHandler onlostpointercapture
;
attribute EventHandler onpointerdown
;
attribute EventHandler onpointermove
;
attribute EventHandler onpointerup
;
attribute EventHandler onpointercancel
;
attribute EventHandler onpointerover
;
attribute EventHandler onpointerout
;
attribute EventHandler onpointerenter
;
attribute EventHandler onpointerleave
;
};
ongotpointercapture
gotpointercapture
イベントタイプ用のイベントハンドラIDL属性([HTML5]参照)。
onlostpointercapture
lostpointercapture
イベントタイプ用のイベントハンドラIDL属性([HTML5]参照)。
onpointerdown
pointerdown
イベントタイプ用のイベントハンドラIDL属性([HTML5]参照)。
onpointermove
pointermove
イベントタイプ用のイベントハンドラIDL属性([HTML5]参照)。
onpointerup
pointerup
イベントタイプ用のイベントハンドラIDL属性([HTML5]参照)。
onpointercancel
pointercancel
イベントタイプ用のイベントハンドラIDL属性([HTML5]参照)。
onpointerover
pointerover
イベントタイプ用のイベントハンドラIDL属性([HTML5]参照)。
onpointerout
pointerout
イベントタイプ用のイベントハンドラIDL属性([HTML5]参照)。
onpointerenter
pointerenter
イベントタイプ用のイベントハンドラIDL属性([HTML5]参照)。
onpointerleave
pointerleave
イベントタイプ用のイベントハンドラIDL属性([HTML5]参照)。
タッチ入力の場合、全てのポインターイベントのデフォルト動作はビューポートの操作(パンやズームなど)であってはなりません。
touch-action
CSSプロパティ名前: | touch-action |
---|---|
値: | auto | none | [ pan-x || pan-y ] |
manipulation
|
初期値: | auto |
適用対象: | 全ての要素(ただし非置換インライン要素・テーブル行・行グループ・テーブル列・列グループは除く) |
継承: | なし |
パーセンテージ: | 該当なし |
メディア: | 視覚 |
算出値: | 指定値と同じ |
touch-action
CSSプロパティは、タッチ入力がユーザーエージェントによるデフォルト動作(パンやズーム等)を引き起こしてもよいかを決定します。詳細はtouch-action
値のセクションを参照。
touch-action
値を考慮すべきです。
ユーザーエージェントによるタッチ動作実行中、ユーザーエージェントは以降そのポインターに対するポインターイベントを発火してはなりません。加えて、以下全てが成立した場合、ユーザーエージェントはそのポインターのイベントストリームを終了するため、pointercancel
(以降pointerout
・1つ以上のpointerleave
イベント)という名前のポインターイベントを発火しなければなりません:
pointerdown
イベントが送信されているpointerdown
に続く)pointerup
またはpointercancel
イベントがまだ送信されていない
ユーザーが要素をタッチした際、その効果はtouch-action
プロパティの値と要素及び祖先のデフォルトタッチ動作によって以下のように決定されます:
touch-action
に準拠するとみなされます。CSS変形が適用されている場合、要素の座標空間はスクリーン座標と異なることがあり、軸の取り扱いも変わります(例:要素が90度回転している場合、要素のX軸はスクリーン座標のY軸と平行になる)。
touch-action
プロパティに準拠していればサポートされます(該当する両要素を含む)。touch-action
値の変更はそのタッチ動作中無視されます。例:pointerdown
ハンドラ内でauto
からnone
に変更しても、そのポインターがアクティブな間はデフォルトタッチ動作の継続・中止には影響しません。
touch-action
値処理方法は本仕様の範囲外です。
touch-action
値の詳細
ユーザーエージェントは、要素上で開始されたタッチについて、列挙された全方向でスクロールを開始する目的に限定して考慮してもよい。スクロール開始後は、逆方向への操作も許容される(逆方向開始が許されない場合でも、開始後の方向転換は可能)。ただしスクロール開始軸が1軸に限定されている場合(例:pan-y
)、スクロール中に軸を変更することはできない。
auto
でサポートされる追加動作は本仕様の範囲外。auto
やnone
値の動作定義は本仕様の範囲外です。
touch-action
プロパティはCSSのwidth
・height
プロパティを両方サポートする要素にのみ適用されます([CSS21]参照)。この制約は低遅延タッチ動作のためのユーザーエージェント最適化を目的としています。デフォルト非対応要素(例:非置換インライン要素<span>
等)には、display: block
等でwidth
・height
両プロパティをサポートさせることができます。将来の仕様で全要素に拡張される可能性があります。
touch-action
の一部デフォルト動作を無効化することで、ユーザーエージェントが他の動作により高速に反応できることがあります。例: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>
このセクションは非規範です。
ポインターキャプチャを使うと、特定のポインター(互換性マウスイベントを含む)のイベントターゲットを、通常のヒットテスト結果とは異なる特定の要素にリターゲットできます。これは、カスタムスライダーコントロール(例:[HTML5]の<input type="range">
コントロールのような)などの場面で有用です。スライダーのつまみ要素にポインターキャプチャを設定することで、ポインターがつまみから外れてもコントロールを左右にスライドできるようになります。
pointerdown
後、ポインターキャプチャを使うことで、ポインターがつまみから外れてもスライド操作が可能になります。
ポインターキャプチャは、element.setPointerCapture(pointerId)
メソッドを呼び出すことで設定できます。このメソッドが呼び出されたとき、ユーザーエージェントは以下の手順を実行しなければなりません:
pointerId
が、いずれのアクティブポインターにも一致しない場合、NotFoundError
という名前のDOMException
をスローする。
Element
が[DOM4]のconnected
でない場合、InvalidStateError
という名前の例外をスローする。
InvalidStateError
という名前の例外をスローする。
pointerId
に対して、保留中のポインターキャプチャ対象の上書きを、このメソッドが呼び出されたElement
に設定する。
ポインターキャプチャは、element.releasePointerCapture(pointerId)
メソッドを明示的に呼び出すことで解除します。このメソッドが呼び出された場合、ユーザーエージェントは以下の手順を実行しなければなりません:
pointerId
が、いずれのアクティブポインターにも一致しない場合、かつこの手順が暗黙のポインターキャプチャ解除によるものでない場合、NotFoundError
という名前のDOMException
をスローする。
Element
がpointerId
に対してhasPointerCaptureがfalseの場合、これらの手順を終了する。
pointerId
に対して、保留中のポインターキャプチャ対象の上書きが設定されていればクリアする。一部の入力デバイス(タッチスクリーンなど)は「ダイレクトマニピュレーション」メタファーを実装しており、ポインターが主にアクティブになったUI要素に作用する(直接接触の物理的錯覚を提供し、UI上に浮かぶカーソルによる間接的接触とは異なる)ようになっています。こうしたデバイスはInputDeviceCapabilities.pointerMovementScrollsプロパティで識別され、「暗黙のポインターキャプチャ」挙動を以下のように持つべきです。
ダイレクトマニピュレーションデバイスは、pointerdown
リスナーが呼び出される直前に、ちょうどsetPointerCapture
がターゲット要素に呼ばれたかのように振る舞うべきです。hasPointerCapture
APIを使って(例:pointerdown
リスナー内で)これが発生したかどうか判定できます。次のポインターイベントが発火する前にreleasePointerCapture
が呼ばれない場合、通常通りgotpointercapture
イベントがターゲットにディスパッチされ、キャプチャが有効であることを示します。
pointerup
またはpointercancel
イベントを発火した直後、ユーザーエージェントは、発火したpointerup
またはpointercancel
イベントのpointerId
について、保留中のポインターキャプチャ対象の上書きをクリアし、必要に応じてlostpointercapture
を発火するために保留中のポインターキャプチャの処理手順を実行しなければなりません()。保留中のポインターキャプチャの処理手順実行後、ポインターがホバーをサポートしている場合、ユーザーエージェントはキャプチャなしの現在位置に合わせて必要な境界イベントも送信しなければなりません。
ユーザーエージェントがclick
イベント発火をサポートしている場合(互換性マウスイベント参照)、暗黙の解除シナリオでclick
およびlostpointercapture
イベントの両方が発火される場合、click
はlostpointercapture
より前に発火されるべきです。
ポインターキャプチャ対象の上書きがconnected
([DOM4])でなくなった場合、保留中のポインターキャプチャ対象の上書きとポインターキャプチャ対象の上書きノードはクリアされるべきであり、該当ポインターについてlostpointercapture
イベントもドキュメントで発火されるべきです。
要素上でポインターロック([PointerLock])が正常に適用された場合、キャプチャ中または保留中のキャプチャ要素がある場合は、releasePointerCapture()
メソッドが呼ばれたかのように手順を実行しなければなりません。
現在のウェブコンテンツの大多数は、Mouse Eventsのみを記述しています。以下は、ユーザーエージェントが汎用ポインター入力をマウスイベントにマッピングし、既存コンテンツとの互換性を保つためのアルゴリズムを示します。
マウスイベントとの互換性マッピングは、本仕様の任意の機能です。既存のレガシーコンテンツとの高い互換性を実現するため、ユーザーエージェントはこの機能のサポートが推奨されます。互換性マウスイベントをサポートしない場合でも、click
やcontextmenu
イベントのサポートが推奨されます(以下の注参照)。
[UIEVENTS]で定義されるclick
イベントと、[HTML5]で定義されるcontextmenu
イベントは、通常UIのアクティベーションに関連し、キーボードなど他の入力デバイスからも発火されるため、互換性マウスイベントとはみなされません。
ユーザーエージェントがclick
やcontextmenu
の発火をサポートする場合、ポインターイベント中にpreventDefault
を呼んでも、それらの発火可否には通常影響しません。互換性マウスイベントではないため、すべてのポインティングデバイス(プライマリでないポインターも含む)でclick
やcontextmenu
は発火されます。
これら高レベルイベント(click
、contextmenu
、focus
、blur
等)とポインターイベントの発火順は定義されておらず、ユーザーエージェントごとに異なります。例えば、あるユーザーエージェントではcontextmenu
がpointerup
の後に発火されることもあり、他の環境ではpointerup
やpointercancel
の前や、ポインターイベントなし(キーボードショートカット等)で発火される場合もあります。
特に記載がない限り、マッピングされたマウスイベントのターゲットは、それぞれのポインターイベントのターゲットと同じであるべきですが、ターゲットがownerDocument
のツリーに参加していない場合、マウスイベントは元のターゲットが削除時点で属していた最近傍の祖先ノードで発火されるべきです。この場合、マウスイベント用の新しいイベントパス(新しいターゲットノード基準)が構築されます。
著者はpointerdown
イベントをキャンセルすることで、特定の互換性マウスイベントの生成を防ぐことができます。
mouseover
、mouseout
、mouseenter
、mouseleave
イベントは、ポインターがダウンしていても常に発火されます。
プライマリポインターのみが互換性マウスイベントを生成できますが、複数のプライマリポインターが同時にアクティブとなり、それぞれが互換性マウスイベントを生成する場合があります。すべての互換性イベントはMouseEventコード上は単一のマウスデバイスからのものと見なされるため、ユーザーエージェントは単一デバイスの観点で互換性マウスイベントの整合性を保証することが推奨されます。マウス遷移イベント(mouseover
、mouseout
、mouseenter
、mouseleave
)については、全イベントターゲットに対する入出状態が[UIEVENTS]で示唆される通りに有効であることが必要です。ユーザーエージェントは、ドキュメント内でレガシーマウスポインターの有効位置を次のように維持することでこれを保証するべきです。
ユーザーエージェントは、pointerdown
・pointerup
・pointermove
イベントの発火直前や、window
でのpointerleave
イベント直前に、以下の手順を実行すべきです:
T
を、発火されるpointerdown
・pointerup
・pointermove
イベントのターゲットとする。pointerleave
イベントの場合はT
を未設定とする。
T
と現在の有効レガシーマウスポインター位置が両方未設定、または両者が等しい場合は手順を終了する。T
にマウスが移動したものとして、[UIEVENTS]のマウス仕様に従いmouseover
、mouseout
、mouseenter
、mouseleave
イベントを発火する。未設定値はウィンドウ外のマウス位置と見なす。
T
に設定する。ユーザーエージェントがホバー対応デバイスのポインターイベントを発火する際、以下の手順を実行すべきです:
isPrimary
プロパティがfalse
の場合、ポインターイベントを発火し、これ以降の手順を終了する。pointerdown
・pointerup
・pointermove
イベント、またはwindow
でのpointerleave
イベントの場合、レガシーマウスポインターの有効位置の追跡に従い互換性マウス遷移イベントを発火する。pointerdown
で、イベントがキャンセルされた場合、当該pointerType
にPREVENT MOUSE EVENT
フラグをセットする。
pointerType
のPREVENT MOUSE EVENT
フラグが未セットで、発火されたポインターイベントが以下の場合:
pointerdown
の場合、mousedown
イベントを発火する。pointermove
の場合、mousemove
イベントを発火する。pointerup
の場合、mouseup
イベントを発火する。pointercancel
の場合、window
でmouseup
イベントを発火する。pointerup
またはpointercancel
の場合、当該pointerType
のPREVENT MOUSE EVENT
フラグをクリアする。
多くのタッチスクリーンなど一部デバイスは、アクティブ状態以外で座標のホバーをサポートしません。既存のマウスイベント用コンテンツでは、マウスがイベントを生成する前提で、次のような性質が期待されます:
mousemove
イベントを生成する。このため、ユーザーエージェントはこれら入力デバイス向けに異なるマッピングを提供する必要があります。ユーザーエージェントがホバー非対応デバイスのポインターイベントを発火する際、以下の手順を実行すべきです:
isPrimary
プロパティがfalse
の場合、ポインターイベントを発火し、これ以降の手順を終了する。pointerover
かつ、当該ポインターでpointerdown
イベントがまだ発火されていない場合、互換性維持のためmousemove
イベントを発火する。
pointerdown
・pointerup
・pointermove
イベント、またはwindow
でのpointerleave
イベントの場合、レガシーマウスポインターの有効位置の追跡に従い互換性マウス遷移イベントを発火する。pointerdown
で、イベントがキャンセルされた場合、当該pointerType
にPREVENT MOUSE EVENT
フラグをセットする。
pointerType
のPREVENT MOUSE EVENT
フラグが未セットで、発火されたポインターイベントが以下の場合:
pointerdown
の場合、mousedown
イベントを発火する。pointermove
の場合、mousemove
イベントを発火する。pointerup
の場合、mouseup
イベントを発火する。pointercancel
の場合、window
でmouseup
イベントを発火する。pointerup
またはpointercancel
の場合、当該pointerType
のPREVENT MOUSE EVENT
フラグをクリアする。
ユーザーエージェントが[TOUCH-EVENTS]で定義されるTouch EventsとPointer Eventsの両方をサポートする場合、本セクションのような互換性マウスイベントは生成すべきではありません。これは、サイトが[TOUCH-EVENTS]で示すモデルに従ってマウスイベントが生成されることを期待している場合、互換性の問題を引き起こす可能性が高いためです。
ホバー非対応のプライマリポインター(例:タッチスクリーンでの単指操作)で要素をアクティベート(click
)した場合、通常以下のイベント順となります:
mousemove
pointerover
pointerenter
mouseover
mouseenter
pointerdown
mousedown
pointermove
・mousemove
イベントpointerup
mouseup
click
pointerout
pointerleave
mouseout
mouseleave
この操作中にpointerdown
イベントがキャンセルされた場合、イベント順は以下の通りとなります:
mousemove
pointerover
pointerenter
mouseover
mouseenter
pointerdown
pointermove
イベントpointerup
click
pointerout
pointerleave
mouseout
mouseleave
この付録では、Pointer Eventsの実装に関するセキュリティとプライバシーについて説明します。内容は本仕様で定義されるイベントモデル、API、イベントの実装によって直接生じるセキュリティ・プライバシー問題に限定します。
本仕様で定義される多くのイベント型は、ユーザーの操作に応じて発火されます。これにより、悪意のあるイベントリスナーが、ユーザーが通常は機密と考える情報、例えばページ上でのユーザーのマウス・スタイラス・指の正確な経路や動きを取得できる可能性があります。
ポインターイベントは、ユーザーのデバイスが対応している場合、ペン入力の角度や傾き、接触面のジオメトリ、スタイラスやタッチスクリーンへの圧力などの追加情報を含みます。角度・傾き・ジオメトリ・圧力の情報はユーザーデバイス上のセンサーに直接関連しているため、本仕様はオリジンにこれらセンサーへのアクセスを許可します。
このセンサーデータや、使用されている入力機構(マウス・タッチ・ペン)の識別能力は、ユーザーやユーザーのデバイス・環境の特徴を推測するために利用される可能性があります。推測された特徴やデバイス・環境情報自体が機微情報となり得る ― 例えば、悪意のあるサイトがユーザーが支援技術を利用しているかどうかを推測することも可能です。また、この情報はユーザープロファイル作成や、特定ユーザーの「フィンガープリント」や追跡の試みにも利用され得ます。
こうしたリスクの軽減策として、ユーザーエージェントは、ユーザーが特定のセンサーデータ(角度・傾き・圧力など)へのアクセスを無効化できる機能や、ユーザーの明示的な同意後のみ利用可能とする機能の導入を検討してもよいでしょう。
これらを除き、ワーキンググループは本仕様について以下のように考えています:
多くの方々から提案や推奨をいただきました。一部は本ドキュメントに採用されています。グループの議長は以下の過去・現在のメンバーおよび参加者の貢献に感謝します: Mustaq Ahmed, Arthur Barstow, Matt Brubeck, Rick Byers, Cathy Chan, Ted Dinklocker, Dave Fleck, Ella Ge, Scott González, Philippe Le Hégaret, Hayato Ito, Patrick Kettner, Patrick H. Lauke, Scott Low, Sangwhan Moon, Olli Pettay, Jacob Rossi, Doug Schepers, Ming-Chou Shih, Brenton Simpson, Dave Tapuska, Asir Vedamuthu, Lan Wei, Navid Zolghadr
このモデルの初版を先駆的に推進してくれた方々にも、特に謝意を表します: Charu Chandiram, Peter Freiling, Nathan Furtwangler, Thomas Olsen, Matt Rakow, Ramu Ramanathan, Justin Rogers, Jacob Rossi, Reed Townsend, Steve Wright。
このセクションは非規範です。
以下は、最初の[PointerEvents1]仕様以降の、本仕様の主要な編集変更点の情報的概要です。本仕様のEditor's Draftsの完全な改訂履歴も参照してください。
[COMPAT]
は純粋に情報的と明記)
ownerDocument
ツリーの記述をDOM4のconnected
概念に置換
fromElement
・toElement
はnull
であるべきとの注を追加
[Exposed=Window]
を追加
hasPointerCapture
を追加touch-action
変更について明確化touch-action
処理モデルを修正