ポインターイベント

レベル2

W3C 勧告

このバージョン:
https://www.w3.org/TR/2019/REC-pointerevents2-20190404/
最新公開バージョン:
https://www.w3.org/TR/pointerevents2/
最新編集者ドラフト:
https://w3c.github.io/pointerevents/
テストスイート:
https://wpt.fyi/pointerevents/
実装報告:
http://w3c.github.io/test-results/pointerevents/all.html
前バージョン:
https://www.w3.org/TR/2019/PR-pointerevents2-20190221/
最新の勧告:
https://www.w3.org/TR/pointerevents1/
編集者:
Matt Brubeck (Mozilla)
Rick Byers (Google)
Patrick H. Lauke (The Paciello Group)
Navid Zolghadr (Google)
参加方法:
GitHub w3c/pointerevents
バグを報告する
コミット履歴
プルリクエスト
メーリングリスト:
メーリングリストアーカイブ

現行標準の公開以降に報告されたエラーや問題については、正誤表を必ずご確認ください。


概要

この仕様書の機能は、マウス、ペン、タッチスクリーンなどのデバイスから、ハードウェア非依存のポインター入力を扱うイベントと関連インターフェイスを記述した、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プロセス文書に準拠しています。

1. はじめに

このセクションは規範的ではありません。

現在、ほとんどの[HTML5]コンテンツは、マウス入力で利用されたり、設計されたりしています。カスタムな方法で入力を処理するものは、一般的に[UIEVENTS]のMouse Eventsを利用してコーディングされます。しかし、今日の新しいコンピューティングデバイスは、タッチスクリーンやペン入力など、他の入力方式も取り入れています。これらの入力方式ごとに個別に処理するためのイベント型も提案されていますが、そのアプローチでは新しい入力タイプへの対応時に、ロジックやイベント処理の重複が発生しやすく、不要なコストがかかります。このことは、コンテンツが一つのデバイスタイプのみを想定して書かれた場合、互換性の問題を生みがちです。さらに、既存のマウスベースのコンテンツとの互換性のため、多くのユーザーエージェントは全ての入力タイプに対してMouse Eventsを発火します。これにより、Mouse Eventが実際のマウスデバイス由来なのか、互換性のために他の入力タイプから生成されたものなのかが曖昧になり、両方のデバイスタイプに同時に対応したコーディングが難しくなります。

複数の入力タイプへのコーディングコストを減らし、上記のMouse Eventsの曖昧さを解消するために、本仕様はより抽象的な入力方式「ポインター」を定義します。ポインターは、マウスカーソル、ペン、タッチ(マルチタッチを含む)、その他のポインティング入力デバイスによる画面上の任意の接触点を表します。このモデルにより、ユーザーがどんなハードウェアを持っていても正しく動作するサイトやアプリケーションが容易に作成できます。デバイス固有の処理が必要な場合には、イベントを発生させたデバイスタイプを判定するためのプロパティも定義しています。主な目的は、クロスデバイスのポインター入力に対して著者が容易にコーディングできる一組のイベントとインターフェイスを提供し、必要な場合にはデバイス固有の処理も拡張できるようにすることです。

もう一つの重要な目的は、マルチスレッドのユーザーエージェントがスクロールなどのデフォルトのタッチアクションを、スクリプト実行によるブロックなしに処理できるようにすることです。

この仕様は様々なポインター入力に対する統一されたイベントモデルを定義していますが、キーボードやキーボードに類似したインターフェイス(例えば、タッチスクリーンのみのデバイス上で動作するスクリーンリーダー等、フォーカス可能なコントロールや要素を順番にナビゲートできる支援技術)など、他の入力形式は対象外です。ユーザーエージェントがこれらのインターフェイスに応じてポインターイベントを生成する選択をする場合もありますが、このシナリオは本仕様の範囲外です。

まずは、著者はfocusblurclickなどの高レベルイベントに応答することで、全ての入力形式に等価な機能を提供することが推奨されます。しかし、Pointer Eventsなどの低レベルイベントを利用する場合、全ての入力タイプをサポートするように配慮してください。キーボードやキーボードに類似したインターフェイスの場合は、明示的なキーボードイベント処理の追加が必要です。詳細についてはWCAG 2.0 ガイドライン 2.1を参照してください。

ポインター入力はマウス、ペン、タッチなどの入力を統合します。
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を参照してください。

2. 適合性

非規範と記載されたセクションだけでなく、本仕様書内の著作ガイドライン、図、例、および注記もすべて非規範です。 それ以外の本仕様書の内容は規範です。

重要な語句 MAY(許可)、MUST(必須)、MUST NOT(禁止)、OPTIONAL(任意)、SHOULD(推奨)、および SHOULD NOT(非推奨)は [RFC2119] に従って解釈されます。

3.

このセクションは非規範です。

以下は、本仕様書のAPIの利用例となる著者コード例です。

例 1: 機能検出とイベントバインド
/* 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', ...);
    ...
}

// キーボード操作用の追加イベントリスナー
...
例 2: ユーザーの入力タイプを検出する
window.addEventListener("pointerdown", detectInputType);

function detectInputType(event) {
    switch(event.pointerType) {
        case "mouse":
            /* マウス入力を検出 */
            break;
        case "pen":
            /* ペン/スタイラス入力を検出 */
            break;
        case "touch":
            /* タッチ入力を検出 */
            break;
        default:
            /* pointerTypeが空(検出不可)またはUA固有のカスタムタイプ */
    }
}
例 3: 基本的なHTML5 Canvasペイントアプリケーション
<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>
例 4: 接触ジオメトリに合わせて要素をリサイズする
<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>
例 5: スクリプトから信頼されていないポインターイベントを発火する
var event = new PointerEvent("pointerover",
  { bubbles: true,
    cancelable: true,
    composed: true,
    pointerId: 42,
    pointerType: "pen",
    clientX: 300,
    clientY: 500
  });
eventTarget.dispatchEvent(event);

4. 用語集

このセクションは非規範です。

アクティブボタン状態
ポインターのbuttonsプロパティが0以外の値を持つ場合の状態。マウスの場合は、少なくとも1つのボタンが押されているとき。タッチの場合は、デジタイザに物理的な接触があるとき。ペンの場合は、ペンがデジタイザに物理的に接触している、またはホバー中に少なくとも1つのボタンが押されているとき。
アクティブポインター
イベントを発生させることができる任意のタッチ接点、ペンスタイラス、マウスカーソル、その他のポインター。特定のポインター(固有のpointerIdで識別)がドキュメント内で追加のイベントを発生させる可能性がある場合、そのポインターはまだアクティブとみなされます。例:
  • デバイスに接続されているマウスは常にアクティブです。
  • 画面上のタッチ接点はアクティブとみなされます。
  • タッチ接点やペンスタイラスがデジタイザの範囲外まで持ち上げられた場合、それはもはやアクティブとはみなされません。
一部のプラットフォームでは、アクティブポインターの集合には、ユーザーエージェント以外(他のアプリケーション向けなど)のすべてのポインター入力が含まれる場合があります。
各アクティブポインターは、[HTML5]で定義されるトップレベル閲覧コンテキストの範囲内で同じidを持つべきです。ただし、複数のトップレベル閲覧コンテキスト間では、その保証はありません。
キャンセルされたイベント
preventDefault()の使用、イベントハンドラでfalseを返す、その他[UIEVENTS]や[HTML5]で定義される手段によって、デフォルト動作が防止されたイベント。
接触ジオメトリ
デジタイザ上の入力(主にタッチ)のバウンディングボックス。この用語は、単一ピクセルより粗いポインター入力解像度を持つデバイスを指す場合が多い。一部のデバイスはこのデータ自体を報告しません。
デジタイザ
入力が接触または近接していることを検知できる表面を持つ入力検知デバイスの一種。最も一般的なのは、タッチ接点やペンスタイラスからの入力を検知する表面です。
ヒットテスト
ユーザーエージェントがポインターイベントのターゲット要素を特定する処理。通常、ポインターの位置とドキュメントの画面メディア上の要素の視覚レイアウトの両方を考慮して決定されます。
ポインター
マウス、ペン、タッチ接点など、画面上の特定座標(または座標群)をターゲットできる入力デバイスのハードウェア非依存な表現。
ユーザーエージェント
一般的にクライアントマシン上で動作し、ユーザーの代理としてコンテンツの取得、解釈、実行、表示、作成を行う、ブラウザやコンテンツオーサリングツールなどのプログラム。
タスクのキューイング
[HTML5]で定義される関連イベントループのイベントタスクキューにタスクを追加すること。

5. ポインターイベントとインターフェイス

5.1 PointerEvent インターフェイス

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は右方向。tiltXtiltYを組み合わせることで、トランスデューサがデジタイザの法線からどれだけ傾いているかを表現できます。ハードウェアやプラットフォームが傾きを報告しない場合は、値は0でなければなりません。

tiltX説明図
2 正のtiltX
tiltY

X-Z平面と、トランスデューサ(ペンスタイラスなど)の軸とX軸を含む平面との間の平面角度(度数、範囲[-90,90])。正のtiltYはユーザー方向。tiltYtiltXを組み合わせることで、トランスデューサがデジタイザの法線からどれだけ傾いているかを表現できます。ハードウェアやプラットフォームが傾きを報告しない場合は、値は0でなければなりません。

tiltY説明図
3 負のtiltY
twist

トランスデューサ(ペンスタイラスなど)が自身の主軸周りに時計回りに回転した度数(範囲[0,359])。ハードウェアやプラットフォームがツイストを報告しない場合は、値は0でなければなりません。

pointerType

イベントを発生させたデバイスタイプ(マウス、ペン、タッチなど)を示します。ユーザーエージェントがマウス、ペンスタイラス、またはタッチ入力デバイス用のポインターイベントを発火する場合pointerTypeの値は以下の表の通りでなければなりません:

ポインターデバイスタイプ pointerType
マウス mouse
ペンスタイラス pen
タッチ接点 touch

ユーザーエージェントがデバイスタイプを検出できない場合は、値は空文字列でなければなりません。上記以外のポインターデバイスタイプをサポートする場合、pointerTypeの値はベンダープレフィックス付きとし、異なるデバイス間での名称衝突を避けるべきです。今後の仕様で他のデバイスタイプ向けの追加規範値が定義される可能性があります

pointerTypeの利用例については例2を参照してください。また、開発者はユーザーエージェントが独自のpointerType値を実装している場合や、単に空文字列の場合に備えて、何らかのデフォルト処理を用意すべきです。
isPrimary

このポインターがこのポインタータイプのプライマリポインターかどうかを示します。

PointerEventInit辞書は、PointerEventインターフェイスのコンストラクターで、信頼されていない(合成)ポインターイベントを構築するための仕組みを提供します。これは[UIEVENTS]で定義されるMouseEventInit辞書を継承します。イベントの構築手順は[DOM4]で定義されています。信頼されていないポインターイベントの発火例についてはを参照してください。

PointerEventインターフェイスは、[UIEVENTS]で定義され、[CSSOM-VIEW]で拡張されるMouseEventを継承します。

5.1.1 ボタン状態

5.1.1.1 複数ボタン同時操作

マウスやペンなど、複数のボタンをサポートするポインターデバイスがあります。[UIEVENTS]のMouse Eventモデルでは、各ボタンの押下ごとにmousedownmouseupイベントが生成されます。こうしたハードウェアの違いをより抽象化し、クロスデバイス入力の記述を簡素化するため、Pointer Eventsでは複数ボタン同時押し(ポインターデバイスの他のボタンがすでに押されている状態で追加のボタンを押す場合)に対し、重複したpointerdownpointerupイベントは発火しません。

代わりに、複数ボタンの同時押しはbuttonおよびbuttonsプロパティの変化を調べることで検出できます。これらbuttonbuttonsプロパティは、[UIEVENTS]のMouseEventインターフェイスから継承されていますが、意味や値が変更されており、詳細は以下のセクションで説明します。

buttonbuttonsプロパティの変更はポインターイベントのみに適用されます。互換性マウスイベントについては、buttonbuttonsの値は[UIEVENTS]に従うべきです。
5.1.1.2 buttonプロパティ

全てのポインターイベント(pointerdownpointerupに限らず)において、buttonプロパティはそのイベントを発火させたデバイスボタンの状態遷移を示します。

デバイスボタンの変化 button
前回イベントからボタン、タッチ/ペン接触の変化なし -1
左マウス
タッチ接触
ペン接触
0
中央マウス 1
右マウス
ペンバレルボタン
2
X1(戻る)マウス 3
X2(進む)マウス 4
ペン消しゴムボタン 5
マウスドラッグ中、pointermoveイベントのbuttonプロパティの値はmousemoveイベントの場合と異なります。例えば、右ボタンを押しながらマウスを動かすと、pointermoveイベントのbutton値は-1ですが、mousemoveイベントのbutton値は2となります。
5.1.1.3 buttonsプロパティ

buttonsプロパティはデバイスボタンの現在の状態をビットマスクで示します(MouseEventと同様ですが、値の種類が拡張されています)。

デバイスボタンの現在の状態 buttons
マウスがボタン未押下で移動
ペンがボタン未押下でホバー移動
0
左マウス
タッチ接触
ペン接触
1
中央マウス 4
右マウス
ペンバレルボタン
2
X1(戻る)マウス 8
X2(進む)マウス 16
ペン消しゴムボタン 32

5.1.2 プライマリポインター

マルチポインター(例:マルチタッチ)シナリオでは、isPrimaryプロパティを使って各ポインタータイプのアクティブポインターの集合の中でマスターポインターを識別します。

  • 任意の時点で、各ポインタータイプごとにプライマリポインターは最大1つのみ存在します。
  • 特定のポインタータイプで最初にアクティブになったポインター(例えば、マルチタッチ操作で最初に画面に触れた指)が、そのポインタータイプのプライマリポインターになります。
  • プライマリポインターだけが互換性マウスイベントを生成します。複数のプライマリポインターがある場合、それぞれが互換性マウスイベントを生成します。
シングルポインター操作のみを意図する場合は、非プライマリポインターを無視することで実現できます(ただし、複数のプライマリポインターに関する以下の注も参照してください)。
複数種類のポインターデバイスが同時に使われている場合、各pointerTypeごとにプライマリとみなされるポインターが存在します。例えば、タッチ接点とマウスカーソルが同時に動いた場合、それぞれがプライマリポインターとみなされます。
一部のデバイス、OS、ユーザーエージェントでは、複数種類のポインター入力の同時利用を無効化して誤操作を防ぐ場合があります。例えば、タッチとペン両対応デバイスでは、ペン操作中はタッチ入力を無視する(ペン操作時に手を画面に置いても誤判定されないようにする、いわゆる「パームリジェクション」)。現時点では著者がこの挙動を抑制する方法はありません。
場合によっては、ユーザーエージェントがどのポインターもプライマリとマークされていないポインターイベントを発火することがあります。例えば、特定のタイプのアクティブポインターが複数(マルチタッチ)ありプライマリポインターが離脱(画面から離れた)した場合、プライマリポインターイベントは発生しなくなります。また、デバイス全体のアクティブポインター(ユーザーエージェント以外のアプリを含む)でプライマリが決まる環境では、最初のタッチがユーザーエージェント外部で使われ、2番目(マルチタッチ)のタッチがユーザーエージェント内で使われた場合、2番目の接点はisPrimaryfalseでポインターイベントが発火される場合があります。
現状のOSやユーザーエージェントでは、複数のマウス入力の概念は通常ありません。複数のマウスデバイス(ノートPCのトラックパッドと外部マウスなど)があっても、全ての動作は単一のマウスポインターに変換され、異なるマウスデバイスのボタン操作の区別もありません。従って、通常はマウスポインターは1つだけで、そのポインターがプライマリになります。

5.1.3 PointerEventインターフェイスによるイベントの発火

eという名前のポインターイベントを発火するとは、[DOM4]で定義されるeという名前のイベントを発火することであり、そのイベントはPointerEventインターフェイスを使い、属性はPointerEventインターフェイスおよび属性とデフォルト動作に従ってセットされます。

イベントがgotpointercaptureまたはlostpointercaptureでない場合、このPointerEventに対して保留中のポインターキャプチャの処理手順を実行します。

イベント発火対象オブジェクトは以下の通り決定されます:

このイベントがpointerdownで、関連デバイスがダイレクトマニピュレーションデバイスかつ対象がElementであれば、ポインターキャプチャの設定pointerIdを対象要素に設定)を暗黙のポインターキャプチャとして行います。

決定された対象にイベントを発火します。

通常のヒットテスト結果ではなくpointer capture target overrideを対象とすることで、境界イベントが発生する場合があります。これはポインターが前の対象から新しいキャプチャ対象へ移動するのと同じで、異なる対象間であれば最初に境界イベントをディスパッチすべきです。キャプチャが解除された場合も同様に、ポインターがキャプチャ対象からヒットテスト対象へ移動することになります。
5.1.3.1 属性とデフォルト動作

本仕様で定義されるイベントタイプのbubblescancelableプロパティおよびデフォルト動作は下表の通りです。各イベントタイプの詳細はポインターイベント型で説明します。

イベントタイプ 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 なし

上記のうちpointerenterpointerleaveを除くすべてのポインターイベントのcomposed([DOM4])属性はtrueであるべきです。 また、上記すべてのポインターイベントのdetail([UIEVENTS])属性は0であるべきです。

多くのユーザーエージェントは、レガシーコンテンツのためにMouseEventに非標準属性fromElementtoElementを公開しています。これらのユーザーエージェントでは、PointerEventで継承されるそれらの属性値はnullにし、標準化された代替(targetrelatedTarget)の利用を促すべきです。

MouseEvents [UIEVENTS]と同様に relatedTargetは、ポインターが離れた(pointeroverpointerenterの場合)要素、またはポインターが入った(pointeroutpointerleaveの場合)要素に初期化されるべきです。他のポインターイベントでは、値はnullになります。なお、要素がポインターキャプチャを取得すると、以降のそのポインターの全イベントはキャプチャ要素の境界内とみなされます。

gotpointercaptureおよびlostpointercaptureについては、上表で定義された属性以外は、ユーザーエージェントが保留中のポインターキャプチャの処理を実行し、gotpointercapturelostpointercaptureイベントを発火した原因となったPointer Eventと同じであるべきです。

5.1.3.2 保留中のポインターキャプチャの処理

ユーザーエージェントは、暗黙のポインターキャプチャ解除時およびgotpointercapturelostpointercapture以外のPointer Eventsを発火する際に、以下の手順を実行しなければなりません

  1. このポインターのpointer capture target overrideが設定されていて、pending pointer capture target overrideと異なる場合、pointer capture target overrideノードでlostpointercaptureという名前のポインターイベントを発火する。
  2. このポインターのpending pointer capture target overrideが設定されていて、pointer capture target overrideと異なる場合、pending pointer capture target overridegotpointercaptureという名前のポインターイベントを発火する。
  3. pending pointer capture target overrideが設定されていれば、pointer capture target overrideをそれに設定する。そうでなければ、pointer capture target overrideをクリアする。

5.2 ポインターイベント型

以下は本仕様で定義されるイベント型です。

プライマリポインターの場合、これらのイベント(gotpointercapturelostpointercaptureを除く)は互換性マウスイベントも発火する場合があります。

5.2.1 pointerover イベント

ユーザーエージェントは、ポインティングデバイスが要素のヒットテスト境界内に移動したとき、pointeroverという名前のポインターイベントを発火しなければなりませんsetPointerCapturereleasePointerCaptureでヒットテスト対象が変わる場合があり、キャプチャ中は境界イベント発火の目的上、常にキャプチャ要素の境界内にいるとみなされます。ホバー非対応デバイスの場合、pointerdownイベント発火前にもこのイベントを発火しなければなりませんpointerdown参照)。

5.2.2 pointerenter イベント

ユーザーエージェントは、ポインティングデバイスが要素またはその子孫のヒットテスト境界内に移動したとき、pointerenterという名前のポインターイベントを発火しなければなりませんpointerdownイベントによる場合も含む、ホバー非対応デバイス参照)。setPointerCapturereleasePointerCaptureでヒットテスト対象が変わる場合があり、キャプチャ中は境界イベント発火の目的上、常にキャプチャ要素の境界内にいるとみなされます。このイベント型はpointeroverと似ていますが、バブリングしない点が異なります。

このイベント型は、[UIEVENTS]で記述されるmouseenterイベントや、[CSS21]で記述されるCSSの:hover疑似クラスと類似点があります。pointerleaveイベントも参照。

5.2.3 pointerdown イベント

ユーザーエージェントは、ポインターがアクティブボタン状態になったとき、pointerdownという名前のポインターイベントを発火しなければなりません。マウスの場合は、ボタンが未押下から1つ以上押下されたとき。タッチの場合は、デジタイザへの物理的接触時。ペンの場合は、ペンがボタン未押下状態でデジタイザに物理接触したとき、またはホバー中にボタン未押下から1つ以上押下されたとき。

マウス(や他の複数ボタンポインターデバイス)の場合、pointerdownpointerupmousedownmouseupと同じ状況すべてで発火するわけではありません。詳細は複数ボタン同時操作を参照。

ホバー非対応デバイスの場合、ユーザーエージェントはpointerdownイベント発火前にpointeroverpointerenterイベントも発火しなければなりません

著者はisPrimaryプロパティがtrueの場合、pointerdownイベントをキャンセルすることで、特定の互換性マウスイベントの発火を防ぐことができます。これによりポインターにPREVENT MOUSE EVENTフラグがセットされます。ただし、mouseovermouseentermouseoutmouseleaveイベントの発火は防げません。

5.2.4 pointermove イベント

ユーザーエージェントは、ポインターの座標が変化したときpointermoveという名前のポインターイベントを発火しなければなりません。また、ボタン状態、圧力、接線圧、傾き、ツイスト、接触ジオメトリ(例:widthheight)が変化し、他のポインターイベントの発火要件に該当しない場合にもpointermoveイベントを発火しなければなりません

5.2.5 pointerup イベント

ユーザーエージェントは、ポインターがアクティブボタン状態を離れたとき、pointerupという名前のポインターイベントを発火しなければなりません。マウスの場合は、ボタンが1つ以上押下から全て未押下に遷移したとき。タッチの場合は、デジタイザから物理的接触がなくなったとき。ペンの場合は、ボタン未押下状態でデジタイザとの物理接触が解除されたとき、またはホバー中に1つ以上押下から全て未押下に遷移したとき。

ホバー非対応デバイスの場合、pointerupイベント発火後にpointeroutpointerleaveイベントも発火しなければなりません

マウス(や他の複数ボタンポインターデバイス)の場合、pointerdownpointerupmousedownmouseupと同じ状況すべてで発火するわけではありません。詳細は複数ボタン同時操作を参照。

5.2.6 pointercancel イベント

ユーザーエージェントは以下の状況でpointercancelという名前のポインターイベントを発火しなければなりません

  • ユーザーエージェントがポインターが今後イベントを発生させる可能性が低いと判断した場合(例:ハードウェアイベントによる)。
  • pointerdownイベント発火後に、そのポインターがページビューポートの操作(パンやズーム)に使われた場合。
    ユーザーエージェントは、複数のポインタータイプ(タッチやペンなど)によるパンやズームを開始できるため、パンやズーム開始時に様々なポインター(異なるpointerTypeも含む)がキャンセルされる場合があります。
  • ドラッグ操作開始[HTML]直前に、その操作を引き起こしたポインターについて。
    ドラッグ操作開始が何らかの手段(例:dragstartイベントでpreventDefaultを呼ぶ)で防がれた場合、pointercancelイベントは発火されません。

pointercancelイベント発火後、ユーザーエージェントはpointeroutpointerleaveイベントも発火しなければなりません

このセクションは非規範です。

ユーザーエージェントがポインターが今後イベントを発生させる可能性が低いと判断するシナリオ例:

  • ポインターがアクティブな状態でデバイスの画面の向きが変更された。
  • ユーザーがデバイスの同時ポインター数上限を超える入力を行った。
  • ユーザーエージェントが入力を誤操作と判断した(例:ハードウェアがパームリジェクションをサポート)。
  • ユーザーエージェントが入力をパンやズームジェスチャと判断した。

デバイスの画面向き変更、誤操作検知、ポインターによるビューポート操作(パンやズーム)方法は本仕様の範囲外です。

5.2.7 pointerout イベント

ユーザーエージェントは以下のいずれかの場合にpointeroutという名前のポインターイベントを発火しなければなりません

  • ポインティングデバイスが要素のヒットテスト境界外に移動した場合。setPointerCapturereleasePointerCaptureでヒットテスト対象が変わる場合があり、キャプチャ中は境界イベント発火の目的上、常にキャプチャ要素の境界内にいるとみなされます。
  • ホバー非対応デバイスでpointerupイベント発火後(pointerup参照)。
  • pointercancelイベント発火後(pointercancel参照)。
  • ペンスタイラスがデジタイザで検知可能なホバー範囲外に離れた場合。

5.2.8 pointerleave イベント

ユーザーエージェントは、ポインティングデバイスが要素およびその子孫すべてのヒットテスト境界外に移動した場合、またはホバー非対応デバイスでpointerupおよびpointercancelイベント発火後(pointeruppointercancel参照)、pointerleaveという名前のポインターイベントを発火しなければなりませんsetPointerCapturereleasePointerCaptureでヒットテスト対象が変わる場合があり、キャプチャ中は境界イベント発火の目的上、常にキャプチャ要素の境界内にいるとみなされます。ペンスタイラスがデジタイザで検知可能なホバー範囲外に離れた場合も発火しなければなりません。このイベント型はpointeroutと似ていますが、バブリングしない・ポインティングデバイスが要素および全子孫の境界外に完全に出るまで発火しない点が異なります。

このイベント型は、[UIEVENTS]で記述されるmouseleaveイベントや、[CSS21]で記述されるCSSの:hover疑似クラスと類似点があります。pointerenterイベントも参照。

5.2.9 gotpointercapture イベント

要素がポインターキャプチャを取得したとき、ユーザーエージェントはgotpointercaptureという名前のポインターイベントを発火しなければなりません。このイベントはキャプチャを受け取る要素で発火され、以降そのポインターのイベントはこの要素で発火されます。詳細はポインターキャプチャの設定および保留中のポインターキャプチャの処理参照。

5.2.10 lostpointercapture イベント

ポインターキャプチャが解除された後、ユーザーエージェントはlostpointercaptureという名前のポインターイベントを発火しなければなりません。このイベントはキャプチャが解除された要素で発火され、以降そのポインターのイベントは通常のヒットテスト機構(本仕様の範囲外)でターゲットが決定されます。詳細はポインターキャプチャの解除暗黙のポインターキャプチャ解除保留中のポインターキャプチャの処理参照。

6. 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で識別されるポインターに対してポインターキャプチャを持つかどうかを示します。特に、pointerIdpending pointer capture target overrideがこの要素に設定されていればtrue、そうでなければfalseとなります。

このメソッドは、setPointerCaptureを呼び出した直後にtrueを返しますが、その要素がまだgotpointercaptureイベントを受け取っていない場合でも同様です。そのため、暗黙のポインターキャプチャpointerdownイベントリスナー内から検出するのに有用です。

7. 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]参照)。

8. Navigator インターフェイスの拡張

Navigatorインターフェイスは[HTML5]で定義されています。本仕様はNavigatorインターフェイスを拡張し、デバイス検出機能を提供します。

partial interface Navigator {
    readonly  attribute long maxTouchPoints;
};
maxTouchPoints

デバイスが同時にサポートする最大タッチ接点数。複数のデジタイザ(例:複数のタッチスクリーン)がある場合、値は各デジタイザごとにサポートされる最大接点数の集合の最大値でなければなりません

例えば、デバイスに3つのタッチスクリーンがあり、それぞれ2、5、10個の同時タッチ接点をサポートする場合、maxTouchPointsの値は10となります。

maxTouchPointsの値が0より大きい場合、ユーザーのデバイスがタッチ入力をサポートしていることを示しますが、ユーザーが実際にタッチ入力を使うかどうかは保証されません。著者は、マウス・ペン・スクリーンリーダー等他の入力手段も考慮すべきです。
maxTouchPointsは、コンテンツの操作モデルが現在のハードウェアで認識できるかどうかを判断するためにしばしば使われます。ハードウェア性能が低いユーザーにはUIの配慮が可能です。正確なタッチ数が分からないプラットフォームでは、認識が保証される最小値が提供されます。したがって、実際に認識されるタッチ数がmaxTouchPoints値を超えることもあります。

9. デフォルトタッチ動作の候補領域の宣言

タッチ入力の場合、全てのポインターイベントのデフォルト動作はビューポートの操作(パンやズームなど)であってはなりません

タッチ操作は意図的にポインターイベントのデフォルト動作に含まれていません。イベントキャンセルへの依存を排除することで、ユーザーエージェントによるパフォーマンス最適化が容易になります。
ビューポート操作(パンやズーム)にポインターが使われる問題は一般的にタッチ入力に限定されますが、一部ユーザーエージェントでは他のポインタータイプ(例:タブレットのペン)でも同様の操作を許可する場合があります。このセクションはそのようなケースにも適用されます(仕様上「タッチ」と記載されていますが)。

9.1 touch-action CSSプロパティ

名前: touch-action
値: auto | none | [ pan-x || pan-y ] | manipulation
初期値: auto
適用対象: 全ての要素(ただし非置換インライン要素・テーブル行・行グループ・テーブル列・列グループは除く)
継承: なし
パーセンテージ: 該当なし
メディア: 視覚
算出値: 指定値と同じ

touch-action CSSプロパティは、タッチ入力がユーザーエージェントによるデフォルト動作(パンやズーム等)を引き起こしてもよいかを決定します。詳細はtouch-actionのセクションを参照。

前述の通り、他のポインタータイプでもデフォルト動作(パンやズーム等)を許可するユーザーエージェントの場合、同じ考慮を行う必要があります。例えば、ペンによるパン/ズームを許可する場合、ユーザーエージェントはtouch-action値を考慮すべきです。

ユーザーエージェントによるタッチ動作実行中、ユーザーエージェントは以降そのポインターに対するポインターイベントを発火してはなりません。加えて、以下全てが成立した場合、ユーザーエージェントはそのポインターのイベントストリームを終了するため、pointercancel(以降pointerout・1つ以上のpointerleaveイベント)という名前のポインターイベントを発火しなければなりません

ユーザーエージェントは、複数の個別ジェスチャを含む複雑なデフォルト動作ジェスチャを実装する場合があります(例:タッチスクリーンでの「フリックでスクロール」)。ユーザーが素早く指を動かしてパンを開始し、指を離しても慣性スクロールが継続、さらに指で追加の「フリック」や逆方向の動作も可能です。本仕様ではジェスチャやデフォルト動作の実装方法を規定しないため、2回目のタッチがポインターイベントを発火するかどうかはユーザーエージェントの裁量です。

9.2 サポートされるタッチ動作の判定

ユーザーが要素をタッチした際、その効果はtouch-actionプロパティの値と要素及び祖先のデフォルトタッチ動作によって以下のように決定されます:

一部ユーザーエージェントは複数同時ポインター(マルチタッチ等)によるタッチ動作もサポートします。複数ポインターのtouch-action値処理方法は本仕様の範囲外です。

9.3 touch-action値の詳細

auto
ユーザーエージェントは、要素上で開始されたタッチに対し、ビューポートのパンやズームなど許可されているタッチ動作を任意に決定してもよい
none
要素上で開始されたタッチは、デフォルトタッチ動作を引き起こしてはならない
pan-x
pan-y

ユーザーエージェントは、要素上で開始されたタッチについて、列挙された全方向でスクロールを開始する目的に限定して考慮してもよい。スクロール開始後は、逆方向への操作も許容される(逆方向開始が許されない場合でも、開始後の方向転換は可能)。ただしスクロール開始軸が1軸に限定されている場合(例:pan-y)、スクロール中に軸を変更することはできない。

manipulation
ユーザーエージェントは、要素上で開始されたタッチについて、スクロールや連続ズームのみを目的として考慮してもよいautoでサポートされる追加動作は本仕様の範囲外。
実装で一般的な追加のtouch-action値は[COMPAT]の定義を参照。
「パン」と「スクロール」は同義と見なされます。パン・スクロールを引き起こすインタラクションやジェスチャ、autonone値の動作定義は本仕様の範囲外です。
touch-actionプロパティはCSSのwidthheightプロパティを両方サポートする要素にのみ適用されます([CSS21]参照)。この制約は低遅延タッチ動作のためのユーザーエージェント最適化を目的としています。デフォルト非対応要素(例:非置換インライン要素<span>等)には、display: block等でwidthheight両プロパティをサポートさせることができます。将来の仕様で全要素に拡張される可能性があります。
touch-actionの一部デフォルト動作を無効化することで、ユーザーエージェントが他の動作により高速に反応できることがあります。例:autoの場合、ダブルタップ検出のためclickに通常300msの遅延が追加されますが、touch-action: nonetouch-action: manipulationを明示的に指定するとこの遅延はなくなります。タップ・ダブルタップジェスチャの判定方法は本仕様の範囲外です。
例 6: 全てのタッチ動作を禁止する
<div style="touch-action: none;">
    この要素は全てのタッチに対してポインターイベントを受け取ります。
</div>
例 7: 横方向のパンのみ許可する
<div style="touch-action: pan-x;">
    この要素は水平方向のパン以外ではポインターイベントを受け取ります。
</div>
例 8: 子領域でタッチ動作を禁止する
<div style="overflow: auto;">
    <div style="touch-action: none;">
        この要素は全てのタッチに対してポインターイベントを受け取ります。
    </div>
    <div>
        この要素のタッチは親の操作に消費される場合があります。
    </div>
</div>
例 9: 中間の親領域でタッチ動作を禁止する
<div style="overflow: auto;">
    <div style="touch-action: pan-y;">
        <div style="touch-action: pan-x;">
            この要素は全てのタッチに対してポインターイベントを受け取ります。
            水平方向パンのみを許可していますが、その間の祖先要素は垂直方向パンのみ許可しています。
            よって、タッチ動作は許可されません。
        </div>
    </div>
</div>

10. ポインターキャプチャ

10.1 はじめに

このセクションは非規範です。

ポインターキャプチャを使うと、特定のポインター(互換性マウスイベントを含む)のイベントターゲットを、通常のヒットテスト結果とは異なる特定の要素にリターゲットできます。これは、カスタムスライダーコントロール(例:[HTML5]の<input type="range">コントロールのような)などの場面で有用です。スライダーのつまみ要素にポインターキャプチャを設定することで、ポインターがつまみから外れてもコントロールを左右にスライドできるようになります。

カスタムボリュームスライダー
4 つまみ要素を左右にスライドして値を選択するカスタムスライダーコントロール例。つまみ上でpointerdown後、ポインターキャプチャを使うことで、ポインターがつまみから外れてもスライド操作が可能になります。

10.2 ポインターキャプチャの設定

ポインターキャプチャは、element.setPointerCapture(pointerId)メソッドを呼び出すことで設定できます。このメソッドが呼び出されたとき、ユーザーエージェントは以下の手順を実行しなければなりません

  1. メソッド引数として指定されたpointerIdが、いずれのアクティブポインターにも一致しない場合、NotFoundErrorという名前のDOMExceptionをスローする。
  2. このメソッドが呼び出されたElementが[DOM4]のconnectedでない場合、InvalidStateErrorという名前の例外をスローする。
  3. ドキュメントがロックされた要素([PointerLock])を持つ場合、このメソッドが呼び出されたら、InvalidStateErrorという名前の例外をスローする。
  4. ポインターがアクティブボタン状態でない場合、これらの手順を終了する。
  5. 指定されたpointerIdに対して、保留中のポインターキャプチャ対象の上書きを、このメソッドが呼び出されたElementに設定する。

10.3 ポインターキャプチャの解除

ポインターキャプチャは、element.releasePointerCapture(pointerId)メソッドを明示的に呼び出すことで解除します。このメソッドが呼び出された場合、ユーザーエージェントは以下の手順を実行しなければなりません

  1. メソッド引数として指定されたpointerIdが、いずれのアクティブポインターにも一致しない場合、かつこの手順が暗黙のポインターキャプチャ解除によるものでない場合、NotFoundErrorという名前のDOMExceptionをスローする。
  2. 指定したElementpointerIdに対してhasPointerCaptureがfalseの場合、これらの手順を終了する。
  3. 指定したpointerIdに対して、保留中のポインターキャプチャ対象の上書きが設定されていればクリアする。

10.4 暗黙のポインターキャプチャ

一部の入力デバイス(タッチスクリーンなど)は「ダイレクトマニピュレーション」メタファーを実装しており、ポインターが主にアクティブになったUI要素に作用する(直接接触の物理的錯覚を提供し、UI上に浮かぶカーソルによる間接的接触とは異なる)ようになっています。こうしたデバイスはInputDeviceCapabilities.pointerMovementScrollsプロパティで識別され、「暗黙のポインターキャプチャ」挙動を以下のように持つべきです。

ダイレクトマニピュレーションデバイスは、pointerdownリスナーが呼び出される直前に、ちょうどsetPointerCaptureがターゲット要素に呼ばれたかのように振る舞うべきです。hasPointerCaptureAPIを使って(例:pointerdownリスナー内で)これが発生したかどうか判定できます。次のポインターイベントが発火する前にreleasePointerCaptureが呼ばれない場合、通常通りgotpointercaptureイベントがターゲットにディスパッチされ、キャプチャが有効であることを示します。

これは[PointerEvents1]からの破壊的変更ですが、ほとんどの既存コンテンツには影響しません。一般的なプラットフォームUX慣習に合致するだけでなく、暗黙キャプチャ設計により、ユーザーエージェントがタッチ移動イベントのヒットテストを開発者の明示的なオプトインなしで省略できる最適化が可能となり、現行主流のネイティブ・Web APIのタッチ入力のパフォーマンス特性と一致します。
さらに、ユーザーエージェントは特定のUIウィジェット(例:input rangeコントロール等)上で全入力デバイスに対して暗黙のポインターキャプチャ挙動を実装する場合があります(フォームコントロール操作時に指がコントロール外へ多少はみ出しても動作するように)。

10.5 暗黙のポインターキャプチャ解除

pointerupまたはpointercancelイベントを発火した直後、ユーザーエージェントは、発火したpointerupまたはpointercancelイベントのpointerIdについて、保留中のポインターキャプチャ対象の上書きをクリアし、必要に応じてlostpointercaptureを発火するために保留中のポインターキャプチャの処理手順を実行しなければなりません()。保留中のポインターキャプチャの処理手順実行後、ポインターがホバーをサポートしている場合、ユーザーエージェントはキャプチャなしの現在位置に合わせて必要な境界イベントも送信しなければなりません。

ユーザーエージェントがclickイベント発火をサポートしている場合(互換性マウスイベント参照)、暗黙の解除シナリオでclickおよびlostpointercaptureイベントの両方が発火される場合、clicklostpointercaptureより前に発火されるべきです

ポインターキャプチャ対象の上書きconnected([DOM4])でなくなった場合、保留中のポインターキャプチャ対象の上書きポインターキャプチャ対象の上書きノードはクリアされるべきであり、該当ポインターについてlostpointercaptureイベントもドキュメントで発火されるべきです

要素上でポインターロック([PointerLock])が正常に適用された場合、キャプチャ中または保留中のキャプチャ要素がある場合は、releasePointerCapture()メソッドが呼ばれたかのように手順を実行しなければなりません。

11. マウスイベントとの互換性マッピング

現在のウェブコンテンツの大多数は、Mouse Eventsのみを記述しています。以下は、ユーザーエージェントが汎用ポインター入力をマウスイベントにマッピングし、既存コンテンツとの互換性を保つためのアルゴリズムを示します。

マウスイベントとの互換性マッピングは、本仕様の任意の機能です。既存のレガシーコンテンツとの高い互換性を実現するため、ユーザーエージェントはこの機能のサポートが推奨されます。互換性マウスイベントをサポートしない場合でも、clickcontextmenuイベントのサポートが推奨されます(以下の注参照)。

[UIEVENTS]で定義されるclickイベントと、[HTML5]で定義されるcontextmenuイベントは、通常UIのアクティベーションに関連し、キーボードなど他の入力デバイスからも発火されるため、互換性マウスイベントとはみなされません。

ユーザーエージェントがclickcontextmenuの発火をサポートする場合、ポインターイベント中にpreventDefaultを呼んでも、それらの発火可否には通常影響しません。互換性マウスイベントではないため、すべてのポインティングデバイス(プライマリでないポインターも含む)でclickcontextmenuは発火されます。

これら高レベルイベント(clickcontextmenufocusblur等)とポインターイベントの発火順は定義されておらず、ユーザーエージェントごとに異なります。例えば、あるユーザーエージェントではcontextmenupointerupの後に発火されることもあり、他の環境ではpointeruppointercancelの前や、ポインターイベントなし(キーボードショートカット等)で発火される場合もあります。

特に記載がない限り、マッピングされたマウスイベントのターゲットは、それぞれのポインターイベントのターゲットと同じであるべきですが、ターゲットがownerDocumentのツリーに参加していない場合、マウスイベントは元のターゲットが削除時点で属していた最近傍の祖先ノードで発火されるべきです。この場合、マウスイベント用の新しいイベントパス(新しいターゲットノード基準)が構築されます。

著者はpointerdownイベントをキャンセルすることで、特定の互換性マウスイベントの生成を防ぐことができます。

マウスイベントはポインターがダウンしている時のみ防止できます。ホバー状態のポインター(例:ボタン未押下のマウス)はマウスイベントを防止できません。さらにmouseovermouseoutmouseentermouseleaveイベントは、ポインターがダウンしていても常に発火されます。

11.1 レガシーマウスポインターの有効位置の追跡

プライマリポインターのみが互換性マウスイベントを生成できますが、複数のプライマリポインターが同時にアクティブとなり、それぞれが互換性マウスイベントを生成する場合があります。すべての互換性イベントはMouseEventコード上は単一のマウスデバイスからのものと見なされるため、ユーザーエージェントは単一デバイスの観点で互換性マウスイベントの整合性を保証することが推奨されます。マウス遷移イベント(mouseovermouseoutmouseentermouseleave)については、全イベントターゲットに対する入出状態が[UIEVENTS]で示唆される通りに有効であることが必要です。ユーザーエージェントは、ドキュメント内でレガシーマウスポインターの有効位置を次のように維持することでこれを保証するべきです

ユーザーエージェントは、pointerdownpointeruppointermoveイベントの発火直前や、windowでのpointerleaveイベント直前に、以下の手順を実行すべきです

  1. Tを、発火されるpointerdownpointeruppointermoveイベントのターゲットとする。pointerleaveイベントの場合はTを未設定とする。
  2. Tと現在の有効レガシーマウスポインター位置が両方未設定、または両者が等しい場合は手順を終了する。
  3. 現在の有効レガシーマウスポインター位置からTにマウスが移動したものとして、[UIEVENTS]のマウス仕様に従いmouseovermouseoutmouseentermouseleaveイベントを発火する。未設定値はウィンドウ外のマウス位置と見なす。
  4. 有効レガシーマウスポインター位置Tに設定する。

11.2 ホバー対応デバイスのマッピング

ユーザーエージェントがホバー対応デバイスのポインターイベントを発火する際、以下の手順を実行すべきです

  1. 発火するポインターイベントのisPrimaryプロパティがfalseの場合、ポインターイベントを発火し、これ以降の手順を終了する。
  2. 発火するポインターイベントがpointerdownpointeruppointermoveイベント、またはwindowでのpointerleaveイベントの場合、レガシーマウスポインターの有効位置の追跡に従い互換性マウス遷移イベントを発火する。
  3. ポインターイベントを発火する。
  4. 発火したポインターイベントがpointerdownで、イベントがキャンセルされた場合、当該pointerTypePREVENT MOUSE EVENTフラグをセットする。
  5. 当該pointerTypePREVENT MOUSE EVENTフラグが未セットで、発火されたポインターイベントが以下の場合:
    • pointerdownの場合、mousedownイベントを発火する。
    • pointermoveの場合、mousemoveイベントを発火する。
    • pointerupの場合、mouseupイベントを発火する。
    • pointercancelの場合、windowmouseupイベントを発火する。
  6. 発火されたポインターイベントがpointerupまたはpointercancelの場合、当該pointerTypePREVENT MOUSE EVENTフラグをクリアする。

11.3 ホバー非対応デバイスのマッピング

多くのタッチスクリーンなど一部デバイスは、アクティブ状態以外で座標のホバーをサポートしません。既存のマウスイベント用コンテンツでは、マウスがイベントを生成する前提で、次のような性質が期待されます:

ホバーは、マウス向けに設計されたコンテンツでUI要素の表示切替(例:「ホバーメニュー」)に使われる場合があります。このようなコンテンツは、ホバー非対応デバイスでは互換性がないことが多いです。本仕様ではこの場合のマッピングや挙動は定義していません。将来の仕様で検討されます。

このため、ユーザーエージェントはこれら入力デバイス向けに異なるマッピングを提供する必要があります。ユーザーエージェントがホバー非対応デバイスのポインターイベントを発火する際、以下の手順を実行すべきです

  1. 発火するポインターイベントのisPrimaryプロパティがfalseの場合、ポインターイベントを発火し、これ以降の手順を終了する。
  2. 発火するポインターイベントがpointeroverかつ、当該ポインターでpointerdownイベントがまだ発火されていない場合、互換性維持のためmousemoveイベントを発火する。
  3. 発火するポインターイベントがpointerdownpointeruppointermoveイベント、またはwindowでのpointerleaveイベントの場合、レガシーマウスポインターの有効位置の追跡に従い互換性マウス遷移イベントを発火する。
  4. ポインターイベントを発火する。
  5. 発火したポインターイベントがpointerdownで、イベントがキャンセルされた場合、当該pointerTypePREVENT MOUSE EVENTフラグをセットする。
  6. 当該pointerTypePREVENT MOUSE EVENTフラグが未セットで、発火されたポインターイベントが以下の場合:
    • pointerdownの場合、mousedownイベントを発火する。
    • pointermoveの場合、mousemoveイベントを発火する。
    • pointerupの場合、mouseupイベントを発火する。
    • pointercancelの場合、windowmouseupイベントを発火する。
  7. 発火されたポインターイベントがpointerupまたはpointercancelの場合、当該pointerTypePREVENT MOUSE EVENTフラグをクリアする。

ユーザーエージェントが[TOUCH-EVENTS]で定義されるTouch EventsとPointer Eventsの両方をサポートする場合、本セクションのような互換性マウスイベントは生成すべきではありません。これは、サイトが[TOUCH-EVENTS]で示すモデルに従ってマウスイベントが生成されることを期待している場合、互換性の問題を引き起こす可能性が高いためです。

ホバー非対応のプライマリポインター(例:タッチスクリーンでの単指操作)で要素をアクティベート(click)した場合、通常以下のイベント順となります:

  1. mousemove
  2. pointerover
  3. pointerenter
  4. mouseover
  5. mouseenter
  6. pointerdown
  7. mousedown
  8. ポインターの移動に応じて0回以上のpointermovemousemoveイベント
  9. pointerup
  10. mouseup
  11. click
  12. pointerout
  13. pointerleave
  14. mouseout
  15. mouseleave

この操作中にpointerdownイベントがキャンセルされた場合、イベント順は以下の通りとなります:

  1. mousemove
  2. pointerover
  3. pointerenter
  4. mouseover
  5. mouseenter
  6. pointerdown
  7. ポインターの移動に応じて0回以上のpointermoveイベント
  8. pointerup
  9. click
  10. pointerout
  11. pointerleave
  12. mouseout
  13. mouseleave

12. セキュリティとプライバシーに関する考慮事項

この付録では、Pointer Eventsの実装に関するセキュリティとプライバシーについて説明します。内容は本仕様で定義されるイベントモデル、API、イベントの実装によって直接生じるセキュリティ・プライバシー問題に限定します。

本仕様で定義される多くのイベント型は、ユーザーの操作に応じて発火されます。これにより、悪意のあるイベントリスナーが、ユーザーが通常は機密と考える情報、例えばページ上でのユーザーのマウス・スタイラス・指の正確な経路や動きを取得できる可能性があります。

ポインターイベントは、ユーザーのデバイスが対応している場合、ペン入力の角度や傾き、接触面のジオメトリ、スタイラスやタッチスクリーンへの圧力などの追加情報を含みます。角度・傾き・ジオメトリ・圧力の情報はユーザーデバイス上のセンサーに直接関連しているため、本仕様はオリジンにこれらセンサーへのアクセスを許可します。

このセンサーデータや、使用されている入力機構(マウス・タッチ・ペン)の識別能力は、ユーザーやユーザーのデバイス・環境の特徴を推測するために利用される可能性があります。推測された特徴やデバイス・環境情報自体が機微情報となり得る ― 例えば、悪意のあるサイトがユーザーが支援技術を利用しているかどうかを推測することも可能です。また、この情報はユーザープロファイル作成や、特定ユーザーの「フィンガープリント」や追跡の試みにも利用され得ます。

こうしたリスクの軽減策として、ユーザーエージェントは、ユーザーが特定のセンサーデータ(角度・傾き・圧力など)へのアクセスを無効化できる機能や、ユーザーの明示的な同意後のみ利用可能とする機能の導入を検討してもよいでしょう。

これらを除き、ワーキンググループは本仕様について以下のように考えています:

A. 謝辞

多くの方々から提案や推奨をいただきました。一部は本ドキュメントに採用されています。グループの議長は以下の過去・現在のメンバーおよび参加者の貢献に感謝します: 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。

B. 改訂履歴

このセクションは非規範です。

以下は、最初の[PointerEvents1]仕様以降の、本仕様の主要な編集変更点の情報的概要です。本仕様のEditor's Draftsの完全な改訂履歴も参照してください。

C. 参考文献

C.1 規範参照

[CSS21]
カスケーディング・スタイル・シート レベル2改訂1(CSS 2.1)仕様。Bert Bos; Tantek Çelik; Ian Hickson; Håkon Wium Lie ほか。W3C。2011年6月7日。W3C勧告。URL: https://www.w3.org/TR/CSS2/
[DOM4]
DOM標準。Anne van Kesteren。WHATWG。現行標準。URL: https://dom.spec.whatwg.org/
[HTML]
HTML標準。Anne van Kesteren; Domenic Denicola; Ian Hickson; Philip Jägenstedt; Simon Pieters。WHATWG。現行標準。URL: https://html.spec.whatwg.org/multipage/
[HTML5]
HTML5。Steve Faulkner; Arron Eicholz; Travis Leithead; Alex Danilo; Sangwhan Moon。W3C。2017年12月14日。W3C勧告。URL: https://www.w3.org/TR/html5/
[PointerLock]
Pointer Lock。Vincent Scheib。W3C。2016年10月27日。W3C勧告。URL: https://www.w3.org/TR/pointerlock/
[RFC2119]
RFCで要求レベルを示すキーワードの使用。S. Bradner。IETF。1997年3月。Best Current Practice。URL: https://tools.ietf.org/html/rfc2119
[UIEVENTS]
UI Events。Gary Kacmarcik; Travis Leithead; Doug Schepers。W3C。2018年11月8日。W3C作業草案。URL: https://www.w3.org/TR/uievents/
[WEBIDL]
Web IDL。Cameron McCormack; Boris Zbarsky; Tobie Langel。W3C。2016年12月15日。W3C編集草案。URL: https://heycam.github.io/webidl/

C.2 情報参照

[COMPAT]
互換性標準。Mike Taylor。WHATWG。現行標準。URL: https://compat.spec.whatwg.org/
[CSSOM-VIEW]
CSSOM View Module。Simon Pieters。W3C。2016年3月17日。W3C作業草案。URL: https://www.w3.org/TR/cssom-view-1/
[PointerEvents1]
Pointer Events。Jacob Rossi; Matt Brubeck。W3C。2015年2月24日。W3C勧告。URL: https://www.w3.org/TR/pointerevents1/
[TOUCH-EVENTS]
Touch Events。Doug Schepers; Sangwhan Moon; Matt Brubeck; Arthur Barstow。W3C。2013年10月10日。W3C勧告。URL: https://www.w3.org/TR/touch-events/