現行標準の公開以降に報告されたエラーや問題については、正誤表を必ずご確認ください。
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, optionalPointerEventIniteventInitDict), 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でなければなりません。
tiltXY-Z平面と、トランスデューサ(ペンスタイラスなど)の軸とY軸を含む平面との間の平面角度(度数、範囲[-90,90])。正のtiltXは右方向。tiltXとtiltYを組み合わせることで、トランスデューサがデジタイザの法線からどれだけ傾いているかを表現できます。ハードウェアやプラットフォームが傾きを報告しない場合は、値は0でなければなりません。
tiltX。tiltYX-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]参照)。
onpointerdownpointerdownイベントタイプ用のイベントハンドラIDL属性([HTML5]参照)。
onpointermovepointermoveイベントタイプ用のイベントハンドラIDL属性([HTML5]参照)。
onpointeruppointerupイベントタイプ用のイベントハンドラIDL属性([HTML5]参照)。
onpointercancel
pointercancelイベントタイプ用のイベントハンドラIDL属性([HTML5]参照)。
onpointeroverpointeroverイベントタイプ用のイベントハンドラIDL属性([HTML5]参照)。
onpointeroutpointeroutイベントタイプ用のイベントハンドラ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がターゲット要素に呼ばれたかのように振る舞うべきです。hasPointerCaptureAPIを使って(例: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)した場合、通常以下のイベント順となります:
mousemovepointeroverpointerentermouseovermouseenterpointerdownmousedownpointermove・mousemoveイベントpointerupmouseupclickpointeroutpointerleavemouseoutmouseleaveこの操作中にpointerdownイベントがキャンセルされた場合、イベント順は以下の通りとなります:
mousemovepointeroverpointerentermouseovermouseenterpointerdownpointermoveイベントpointerupclickpointeroutpointerleavemouseoutmouseleaveこの付録では、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処理モデルを修正