ポインターイベント

レベル 3

W3C 候補勧告スナップショット

この文書の詳細
このバージョン:
https://www.w3.org/TR/2025/CR-pointerevents3-20251106/
最新公開バージョン:
https://www.w3.org/TR/pointerevents3/
最新編集者ドラフト:
https://w3c.github.io/pointerevents/
履歴:
https://www.w3.org/standards/history/pointerevents3/
コミット履歴
テストスイート:
https://wpt.fyi/pointerevents/
実装レポート:
https://wpt.fyi/pointerevents/
最新の勧告:
https://www.w3.org/TR/pointerevents2
編集者:
Patrick H. Lauke (TetraLogical)
Robert Flack (Google)
以前の編集者:
Matt Brubeck (Mozilla)
Rick Byers (Google)
Navid Zolghadr (Google)
フィードバック:
GitHub w3c/pointerevents (プルリクエスト, 新規イシュー, オープンイシュー)
public-pointer-events@w3.org 件名 [pointerevents3] … メッセージのトピック … (アーカイブ)
ブラウザー対応状況:
caniuse.com

要約

本仕様の機能は、ポインターイベントに含まれる機能を拡張または修正します。ポインターイベントは、マウス、ペン、タッチスクリーンなど、ハードウェアに依存しないポインター入力の取り扱いのためのイベントおよび関連インターフェースを記述したW3C勧告です。既存のマウスベースのコンテンツとの互換性のために、本仕様では他のポインター入力機器タイプにおいてもマウスイベントを発火させるマッピングについても記載しています。

この文書のステータス

このセクションは、本 文書の公開時点におけるステータスを説明します。現在のW3C の公開文書および本技術レポートの最新版は、 W3C標準およびドラフト一覧で確認できます。

本仕様は [PointerEvents2] の更新版です。

この改訂には新機能が含まれます:

この改訂にはまた次の明確化も含みます:

本仕様が候補勧告から進む前に、2つ以上の独立した実装がそれぞれのテストに合格する必要がありますが、全てのテストに単一実装が合格する必要はありません。

この文書はPointer Events Working Groupによって、 Recommendation trackに沿って候補勧告スナップショットとして公開されました。

候補勧告として公開されることは、W3Cおよびその会員による支持を意味するものではありません。候補勧告スナップショットは 広範なレビューを受けており、 実装経験の収集を目的としており、作業グループメンバーから ロイヤリティフリーライセンスについて のコミットメントを受けています。

この候補勧告は2025年12月4日より早く提案勧告へ進むことはありません。

この文書は、 W3C 特許ポリシー に従って活動するグループによって作成されました。 W3C本グループの成果物に関する特許開示の公開リスト を管理しています。このページには特許の開示方法も記載されています。ある個人が 特許がEssential Claim(s)を含むと信じる場合は、 W3C特許ポリシー第6節にしたがって 情報の開示が必要です。

この文書は 2025年8月18日版 W3Cプロセス文書 に従います。

1. はじめに

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

現在、ほとんどの[HTML]コンテンツはマウス入力で使用されたり、マウス入力用に設計されています。入力をカスタムの方法で処理するものは、通常[UIEVENTS]のMouse Eventsに対応してコーディングされています。しかし現在の新しいコンピューティングデバイスは、タッチスクリーンやペン入力など、他の入力形態を取り入れています。これらの各入力形態を個別に処理するためのイベントタイプが提案されてきました。しかしこのアプローチでは、新しい入力タイプへの対応を追加する際、論理やイベント処理の重複や負荷を引き起こしがちです。これは1つのデバイス種だけを想定してコンテンツが作られる場合、しばしば互換性の問題を生じさせます。さらに、既存のマウスベースコンテンツとの互換性のため、ほとんどのユーザーエージェントは、全ての入力タイプでMouse Eventsを発火します。これにより、Mouse Eventが実際のマウス機器によるものなのか、互換性のために他の入力タイプから生成されたものなのか不明確になり、両方のデバイスタイプに同時に対応したコーディングが難しくなります。

複数の入力タイプへのコーディングコストを低減し、また上記のMouse Eventsに関する曖昧さを解消するため、この仕様ではポインターと呼ばれる、より抽象的な入力の形を定義します。ポインターとは、マウスカーソル、ペン、タッチ(マルチタッチ含む)、その他のポインティング入力機器による画面上の任意の接触点を指します。このモデルにより、ユーザーのハードウェアにかかわらず正常に動作するサイトやアプリケーションの作成が容易になります。デバイス固有の制御をしたい場合には、そのイベントを発生させたデバイスタイプを調べるためのプロパティも規定されています。主な目的は、必要に応じてデバイス固有の制御も可能にしながら、クロスデバイスポインター入力に対してより簡単にコーディングできる統一されたイベントとインターフェースを提供することです。

もう一つの重要な目的として、ユーザーエージェントがスクリプトの実行をブロックすることなく、直接操作によるパンやズーム(たとえばタッチスクリーンに対する指やスタイラスの操作)をマルチスレッドで処理できるようにすることがあります。

注記

この仕様はさまざまなポインター入力に対する統一的なイベントモデルを定義しますが、このモデルはキーボードやキーボードに似たインターフェース(たとえば画面読み上げソフトや、フォーカス可能なコントロールや要素を順番に移動できるような、タッチスクリーンのみのデバイス上で稼働する支援技術など)のようなその他の入力形態は対象外です。ユーザーエージェントによっては、そうしたインターフェースに対してもポインターイベントを生成することを選択する場合がありますが、この仕様ではそのシナリオは対象外です。

まずは、著者はfocusblurclickといった高レベルイベントに対応することで、全ての入力方式に等価な機能を提供することを推奨します。ただし、低レベルイベント(ポインターイベントなど)を使う場合は、すべての入力種別に対応していることを確認してください。キーボードやキーボード型インターフェースの場合は、明示的なキーボードイベント対応の追加が必要かもしれません。詳細はキーボードアクセス可能 [WCAG22] を参照してください。

ポインター入力はマウス、ペン、タッチなど様々な入力ソースを統合します
1 ポインターは、画面上の特定の座標(または座標群)をターゲットできる入力機器群のハードウェア非依存な表現です。

汎用的なポインター入力のためのイベントは、マウスのイベントと非常によく似ています:pointerdownpointermovepointeruppointeroverpointeroutなどです。これにより、Mouse EventsからPointer Eventsへの容易な移行が可能となります。 Pointer Eventsは、Mouse Eventsと同様にclient座標、ターゲット要素、ボタンの状態などのプロパティに加え、他の入力形態に合わせて圧力や接触ジオメトリ、傾きなど新たなプロパティも提供します。著者はPointer Eventsを利用して、入力種別ごとに適宜ロジックを共通化したり、必要に応じて特定の入力タイプ向けの最適化も容易に行えます。

Pointer Eventsはさまざまな入力機器から発生しますが、他のデバイス固有のイベントから生成されるものと定義されているわけではありません。互換性のために推奨される場合もありますが、本仕様では他のデバイス固有イベント(マウスイベントやタッチイベント等)のサポートを義務付けていません。ユーザーエージェントはPointer Eventsのみをサポートし、他のデバイスイベントをサポートしなくてもかまいません。マウス固有イベント向けに書かれたコンテンツとの互換性のため、本仕様ではマウス以外の機器からのポインター入力を元に互換性マウスイベントを生成する方法についても、参考として記載しています。

注記

本仕様は、[TOUCH-EVENTS] で定義されるTouch EventsとPointer Eventsの両方に対応するユーザーエージェントの動作について助言するものではありません。これら2つの仕様の関係についての詳細は、Touch Events Community Groupを参照してください。

2. 適合性

非規範的と記載されたセクションのほか、本仕様におけるすべての著者指針、図式、例、および注記は規範的ではありません。それ以外は全て規範的内容です。

この文書における MAYMUSTMUST NOTOPTIONALSHOULD というキーワードは、 BCP 14 [RFC2119]および [RFC8174] で示されるとおり、ここに示すようにすべて大文字で現れる場合に、かつその場合にのみ解釈されます。

3.

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

以下に、本仕様のAPIの一部の使用例を示します。より具体的な例は、各該当セクションにも記載されています。

1: 機能検出とイベントバインディング
/* Pointer Events または従来の touch/mouse にバインドする */

if (window.PointerEvent) {
    // Pointer Events がサポートされている場合は pointer 系のみをリッスン
    target.addEventListener("pointerdown", function(e) {
        // 必要に応じてe.pointerTypeで入力タイプごとにロジックを分岐
        // (touch/pen/mouseごとの処理)
        ...
    });
    ...
} else {
    // 従来の touch/mouse 用イベントハンドラ
    target.addEventListener('touchstart', function(e) {
        // 互換マウスイベントやclickの発生を防ぐ
        e.preventDefault();
        ...
    });
    ...
    target.addEventListener('mousedown', ...);
    ...
}

// キーボード対応用のイベントリスナー追加など
...
2: ユーザーの入力タイプの検出
window.addEventListener("pointerdown", detectInputType);

function detectInputType(event) {
    switch(event.pointerType) {
        case "mouse":
            /* マウス入力 */
            break;
        case "pen":
            /* ペン/スタイラス入力 */
            break;
        case "touch":
            /* タッチ入力 */
            break;
        default:
            /* pointerTypeが空(検出不可)またはUA固有カスタムタイプ */
    }
}
3: 接触ジオメトリに合わせて要素のサイズを変更
<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>
4: スクリプトから非信頼ポインターイベントを発火
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);

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

4.1 PointerEvent インターフェース

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;
    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;
    [SecureContext] sequence<PointerEvent> getCoalescedEvents();
    sequence<PointerEvent> getPredictedEvents();
};
pointerId

イベントを引き起こしたポインターの一意な識別子。ユーザーエージェントは、プライマリマウスポインターのために汎用のpointerId0 または 1を予約してもよい(MAY)。pointerId-1は予約され、ポインティングデバイス以外によって生成されたイベントを示すために使用しなければならない(MUST)。その他のポインターについて、ユーザーエージェントはpointerId値の割り当て方法において、さまざまな戦略や手法を実装してもよい。なお、アクティブなポインターは[HTML]で定義されるトップレベル閲覧コンテキスト内で一意でなければならず、識別子は他のトップレベル閲覧コンテキストに影響されてはならない(MUST NOT)。(すなわち、あるトップレベル閲覧コンテキストは、そのポインターが閲覧コンテキスト外に移動して別のトップレベル閲覧コンテキストに入ったときに、同じpointerIdになると仮定できない)。

ユーザーエージェントは、過去のアクティブなポインターからすでに引退したpointerIdを再利用してもよい(MAY)。または、特定のポインティングデバイスに対して常に同じpointerIdを再使用してもよい(たとえば、マルチユーザーの協調アプリケーションで特定ユーザーの特定のペン/スタイラス入力を一意に識別するため)。ただし後者の場合、フィンガープリントやページ/ドメイン間の追跡の可能性を最小化するために、そのpointerIdは当該ページ/セッションの存続期間において明示的にその特定のポインティングデバイスのみに紐づくべきであり(MUST)、そのデバイスが新しいセッションで再び使用される際には新たにランダム化されたpointerIdを選ばなければならない(MUST)。

注記

pointerIdの選択アルゴリズムは実装依存です。著者は、他のアクティブなポインターと異なる一意な識別子であること以外の意味を持つと仮定すべきではありません。例として、ユーザーエージェントは、アクティブになった順に0から番号を単純に割り当てる場合がありますが、これらの値が単調増加であることは保証されません。特定のポインティングデバイスに対して同じpointerIdを再使用するかどうかは個々の実装に委ねられているため、著者がこれに依存することは強く推奨されません。

width

ポインターの接触ジオメトリの、CSS ピクセル([CSS21]参照)におけるX軸方向の大きさ。与えられたポインターに対して、この値は各イベントで更新されてもよい(MAY)。通常、接触ジオメトリを持たない入力(伝統的なマウスなど)や、ハードウェアが実際のジオメトリを検出しない場合、ユーザーエージェントはデフォルト値1を返さなければならない(MUST)。

height

ポインターの接触ジオメトリの、CSS ピクセル([CSS21]参照)におけるY軸方向の大きさ。与えられたポインターに対して、この値は各イベントで更新されてもよい(MAY)。通常、接触ジオメトリを持たない入力(伝統的なマウスなど)や、ハードウェアが実際のジオメトリを検出しない場合、ユーザーエージェントはデフォルト値1を返さなければならない(MUST)。

pressure

ポインター入力の正規化された圧力を[0,1]の範囲で表す。01はそれぞれ、ハードウェアが検出可能な最小および最大圧力を表す。圧力をサポートしないハードウェアやプラットフォームでは、アクティブボタン状態のとき値は0.5、それ以外は0でなければならない(MUST)。

tangentialPressure

ポインター入力の正規化された接線圧(別名バレル圧)。範囲は[-1,1]で、0はコントロールの中立位置を意味する。ハードウェアによっては[0,1]の正の値のみをサポートする場合がある。接線圧をサポートしないハードウェアやプラットフォームでは、値は0でなければならない(MUST)。

注記
プロパティ名とは裏腹に、実際にはこのプロパティの値を生成するハードウェアのコントロール/センサーが必ずしも圧力感知であるとは限りません。たとえば多くの場合、エアブラシ用スタイラスの指先ホイールは自由に設定でき、ゼロ位置に戻らないように継続的な圧力をかけ続ける必要はありません。
tiltX

Y-Z平面と、トランスデューサ(例:ペン/スタイラス)の軸とY軸を含む平面とのなす角(度単位、[-90,90]の範囲)。正のtiltXは右方向(X値が増加する方向)。tiltXtiltYと組み合わせて、デジタイザに対するトランスデューサの法線からの傾きを表現できる。傾きや角度を報告しないハードウェアやプラットフォームでは、値は0でなければならない(MUST)。

tiltX の説明図
2 正の tiltX
tiltY

X-Z平面と、トランスデューサ(例:ペン/スタイラス)の軸とX軸を含む平面とのなす角(度単位、[-90,90]の範囲)。正のtiltYはユーザー側(Y値が増加する方向)。tiltYtiltXと組み合わせて、デジタイザに対するトランスデューサの法線からの傾きを表現できる。傾きや角度を報告しないハードウェアやプラットフォームでは、値は0でなければならない(MUST)。

tiltY の説明図
3 正の 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 例: altitudeAngleπ/4(X-Y 平面から45度)。
azimuthAngle

トランスデューサ(例:ペン/スタイラス)の方位角(ラジアン)。範囲は[0, 2π]で、0はX-Y平面上でキャップがX値増加方向(真上から見て「3時」方向)を向く状態を表し、時計回りに値が増加する(「6時」でπ/2、「9時」でπ、「12時」で3π/2)。トランスデューサが表面に完全に垂直(altitudeAngleπ/2)な場合、値は0でなければならない(MUST)。傾きや角度を報告しないハードウェアやプラットフォームでは、値は0でなければならない(MUST)。

azimuthAngle の説明図
5 例: azimuthAngleπ/6(「4時」)。
pointerType

イベントを引き起こしたデバイスの種類(mouse, pen, touch など)を示す。ユーザーエージェントがマウス、ペン/スタイラス、またはタッチ入力デバイスに対してポインターイベントを発火する場合、pointerType の値は次の表に従わなければならない(MUST)。

ポインターデバイスの種類 pointerType の値
Mouse mouse
Pen / stylus pen
Touch contact touch

ユーザーエージェントがデバイスの種類を検出できない場合、値は空文字列でなければならない(MUST)。上記以外のポインターデバイスの種類をサポートする場合、異なるデバイス間で名称が衝突しないように、pointerType の値にはベンダープレフィックスを付与するべきである(SHOULD)。将来の仕様で他のデバイス種別に対する追加の規範的値が提供される可能性がある(MAY)。

注記
基本的な pointerType の使い方については 例 2 を参照のこと。開発者は、ユーザーエージェントが独自のカスタム pointerType 値を実装している場合や、pointerType が空文字列となる状況に対応するために、デフォルトの処理を含めておくべきである。
isPrimary

このポインタータイプの中で、ポインターがプライマリポインターを表すかどうかを示す。

getCoalescedEvents()

合成イベントのリストを返すメソッド。

getPredictedEvents()

予測イベントのリストを返すメソッド。

PointerEventInit 辞書は、PointerEvent インターフェースのコンストラクターにより、信頼されない(合成)ポインターイベントを構築する仕組みを提供するために使用される。[UIEVENTS]で定義される MouseEventInit 辞書を継承する。非信頼ポインターイベントの発火方法については を参照。

イベント構築手順において、PointerEvent は、PointerEventInitcoalescedEvents合成イベントリストにクローンし、 PointerEventInitpredictedEvents予測イベントリストにクローンする。

注記
PointerEvent インターフェースは UI Events で定義される MouseEvent を継承する。 また、CSSOM View Module における提案(各種座標プロパティを long から double に変更して小数座標を可能にする)にも留意すること。すでにこの提案を PointerEvent には実装しているが、通常の MouseEvent には実装していないユーザーエージェントについては、clickauxclickcontextmenu イベントに関する追加要件がある。

4.1.1 ボタンの状態

4.1.1.1 複数ボタンの組み合わせ操作

マウスやペンなど、複数のボタンをサポートするポインターデバイスがある。[UIEVENTS] のマウスイベントモデルでは、各ボタンの押下が mousedownmouseup を生成する。ハードウェア差異をより抽象化し、クロスデバイスの入力実装を簡素化するため、ポインターイベントは重複するpointerdownpointerup を、組み合わせボタンの押下(すでに別のボタンが押下された状態で追加のボタンを押し込むこと)に対しては発火しない。

代わりに、組み合わせボタンの押下は buttonbuttons プロパティの変化を検査することで検出できる。buttonbuttonsMouseEvent インターフェースから継承されるが、意味と値は次節で述べるとおり変更される。

これらの buttonbuttons の変更はポインターイベントにのみ適用される。ただし clickauxclickcontextmenu に関しては、button および buttons の値は [UIEVENTS] に従わなければならない(MUST)。これは 互換マウスイベント と同様である。

4.1.1.2 button プロパティ

任意のポインターイベント(pointerdownpointerup に限らず)におけるボタン状態の遷移を識別するために、button プロパティは、そのイベントを発火させたデバイスボタンを示す。

デバイスボタンの変化 button
前回イベントからボタンやタッチ/ペン接触に変化なし -1
左マウス,
タッチ接触,
ペン接触
0
中ボタン(マウス) 1
右マウス,
ペンのバレルボタン
2
X1(戻る)マウス 3
X2(進む)マウス 4
ペンの消しゴムボタン 5
注記
マウスドラッグ中、pointermove イベントの button 値は mousemove のそれと異なる。たとえば右ボタンを押しながらマウスを移動すると、pointermovebutton は -1、mousemovebutton は 2 となる。
4.1.1.3 buttons プロパティ

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

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

4.1.2 プライマリポインター

マルチポインター(例:マルチタッチ)のシナリオでは、isPrimary プロパティは、各ポインタータイプのアクティブなポインター集合の中からマスターポインターを識別するために使用される。

  • 任意の時点で、各ポインタータイプにつきプライマリポインターは最大1つに限られる。
  • 特定のポインタータイプにおいて最初にアクティブになったポインター(例:マルチタッチ操作で最初に画面に触れた指)が、そのタイプのプライマリポインターとなる。
  • プライマリポインターのみが 互換マウスイベント を生成する。複数のプライマリポインターが存在する状況では、これらのポインターはすべて互換マウスイベントを生成する。
注記
単一ポインターのインタラクションを望む著者は、非プライマリのポインターを無視することでこれを実現できる(ただし、複数のプライマリポインターに関する注記を参照)。
注記
2種類以上のポインターデバイスが同時に使用されている場合、複数のポインター(各 pointerType ごとに1つ)がプライマリと見なされる。例:タッチ接触とマウスカーソルが同時に動いた場合、両方ともプライマリと見なされる。
注記
デバイス、OS、ユーザーエージェントによっては、偶発的なインタラクションを避けるために複数種類のポインター入力の同時使用を無視する場合がある。たとえば、タッチとペンの両方に対応するデバイスでは、ユーザーがペンを使用中はタッチ入力を無視し、ユーザーがペン使用中に手のひらを画面に置けるようにする(一般に「パームリジェクション」と呼ばれる機能)。現在、この挙動を著者が抑制することはできない。
注記
状況によっては、プライマリポインターとしてマークされたポインターが存在しない状態でポインターイベントが発火することがある。たとえば、特定タイプのアクティブなポインターが複数ある(マルチタッチ等)ときにプライマリポインターが取り除かれる(例:画面から離れる)と、プライマリポインターが存在しなくなる場合がある。また、デバイス上で同タイプのすべてのアクティブなポインター(ユーザーエージェント以外のアプリに向けられているものを含む)を用いてプライマリポインターが決定されるプラットフォームでは、最初の(プライマリ)ポインターがユーザーエージェント外にあり、他の(非プライマリ)ポインターがユーザーエージェント内に向けられている場合、ユーザーエージェントisPrimaryfalse として他のポインターのイベントを発火してもよい(MAY)。
注記
現在のOSやユーザーエージェントには、通常、複数マウス入力の概念がない。複数のマウスデバイスが存在する場合(例:トラックパッドと外付けマウスを備えたノートPC)、すべてのマウスデバイスは一般的に単一のデバイスとして扱われる—いずれのデバイスの移動も単一のマウスポインターの移動に変換され、デバイス間でボタン押下の区別はない。このため通常、マウスポインターは1つだけであり、そのポインターがプライマリになる。

4.1.3 PointerEvent インターフェースを用いたイベントの発火

ポインターイベントを発火することは、e という名前のイベントを発火し、PointerEvent を用いて、PointerEvent インターフェースおよび 属性とデフォルトアクションで定義されるとおりに属性を設定することを意味する。

イベントが gotpointercapturelostpointercaptureclickauxclickcontextmenu のいずれでもない場合、この PointerEvent に対して 保留中のポインターキャプチャの処理手順を実行する。

イベントが発火されるターゲットを次のようにして決定する:

targetDocument を、ターゲットの ノードドキュメント [DOM] とする。

イベントが pointerdownpointermove、または pointerup の場合、当該イベントの アクティブドキュメントを、そのイベントのpointerIdに対して targetDocument に設定する。

イベントが pointerdown で、関連デバイスが直接操作デバイスであり、ターゲットが Element の場合、ポインターキャプチャを設定し、当該pointerIdのターゲット要素に対して 暗黙のポインターキャプチャとして記述されるとおりに設定する。

このイベントを発火する前に、ユーザーエージェントは、イベント順序を確保 [UIEVENTS] する目的で、ポインティングデバイスが previousTarget からターゲットへ移動したかのようにターゲットを扱うべきである(SHOULD)。needsOverEvent フラグが設定されている場合、ターゲット要素が同じであっても pointerover イベントが必要である。

決定したターゲットにイベントを発火する。

決定したターゲットを該当ポインターの previousTarget として保存し、needsOverEvent フラグを false にリセットする。previousTarget が、ある時点で [DOM] の connected でなくなる場合、previousTarget を、previousTarget へのイベントディスパッチに対応するイベントパスに従って、いまだ connected [DOM] である最も近い親に更新し、needsOverEvent フラグを true に設定する。

注記
通常のヒットテスト結果ではなく ポインターキャプチャのターゲット上書きをターゲットとして用いると、[UIEVENTS] に定義される境界イベントが発火することがある。これは、ポインターが以前のターゲットから離れて新しいキャプチャターゲットに入るのと同様である。キャプチャが解除されると、ポインターがキャプチャターゲットを離れてヒットテストのターゲットに入るため、同様の状況が発生し得る。
4.1.3.1 属性とデフォルトアクション

本仕様で定義されるイベントタイプの bubbles および cancelable プロパティとデフォルトアクションは、以下の表に示す。各イベントタイプの詳細は ポインターイベントの種類 を参照。

イベントタイプ バブル キャンセル可 デフォルトアクション
pointerover Yes Yes なし
pointerenter No No なし
pointerdown Yes Yes 可変:ポインターがプライマリのとき、mousedown のすべてのデフォルトアクション
このイベントをキャンセルすると、続く 互換マウスイベント の発火も防止される。
pointermove Yes Yes 可変:ポインターがプライマリのとき、mousemove のすべてのデフォルトアクション
pointerrawupdate Yes No なし
pointerup Yes Yes 可変:ポインターがプライマリのとき、mouseup のすべてのデフォルトアクション
pointercancel Yes No なし
pointerout Yes Yes なし
pointerleave No No なし
gotpointercapture Yes No なし
lostpointercapture Yes No なし

ビューポートの操作(パンやズーム)— 一般には 直接操作 の結果として発生する — は、意図的にポインターイベントのデフォルトアクションではない。つまり、これらの挙動(例:タッチスクリーン上で指を動かすことによるページのパン)は、ポインターイベントをキャンセルしても抑制できない。著者は代わりに touch-action を用いて、文書領域に対して明示的に 直接操作の挙動 を宣言しなければならない。イベントキャンセルへの依存を取り除くことで、ユーザーエージェントによるパフォーマンス最適化が容易になる。

pointerenter および pointerleave イベントについては、composed [DOM] 属性は false であるべきである(SHOULD)。上記の他のすべてのポインターイベントでは、属性は true であるべきである(SHOULD)。

上記のすべてのポインターイベントについて、[UIEVENTS] の detail 属性は 0 であるべきである(SHOULD)。

注記
多くのユーザーエージェントは、レガシーコンテンツをサポートするために MouseEvent に非標準属性 fromElementtoElement を公開している。これらの(継承された)属性の値を PointerEvent でも null に設定し、標準化された代替(targetrelatedTarget)への移行を促すことを推奨する。

MouseEventrelatedTarget と同様に、relatedTarget は、(pointerover または pointerenter の場合)ポインターが直前に離れた要素、または(pointerout または pointerleave の場合)ポインターがこれから入る要素に初期化されるべきである。他のポインターイベントでは、この値はデフォルトで null となる。なお、ある要素がポインターキャプチャを受けると、そのポインターに対する以後のイベントはすべてキャプチャ要素の境界内にあるものと見なされる。

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

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

ユーザーエージェントは、ポインターキャプチャを暗黙的に解除する場合や、gotpointercapturelostpointercapture 以外のポインターイベントを発火する場合に、以下の手順を実行しなければならない(MUST)。

  1. このポインターに対するポインターキャプチャのターゲット上書きが設定されており、保留中のポインターキャプチャのターゲット上書きと等しくない場合、lostpointercapture という名前のポインターイベントを ポインターキャプチャのターゲット上書きノードで発火する。
  2. このポインターに対する保留中のポインターキャプチャのターゲット上書きが設定されており、ポインターキャプチャのターゲット上書きと等しくない場合、gotpointercapture という名前のポインターイベントを 保留中のポインターキャプチャのターゲット上書きで発火する。
  3. ポインターキャプチャのターゲット上書きを、設定されていれば 保留中のポインターキャプチャのターゲット上書きに設定する。そうでなければ、ポインターキャプチャのターゲット上書きをクリアする。
注記

clickauxclickcontextmenu イベントのセクションで定義されるとおり、lostpointercapture イベントがディスパッチされた後でも、対応する clickauxclickcontextmenu(該当するもの)がキャプチャ先のターゲットにディスパッチされる。

4.1.3.3 ポインターイベントストリームの抑制

ユーザーエージェントは、特定の pointerId に関するポインターイベントを、そのウェブページが引き続き受け取る可能性が低いと検出した場合、MUST ポインターイベントストリームを抑制しなければならない。次のいずれかのシナリオがこの条件を満たす(他にもシナリオが存在してもMAY)。

  • ユーザーエージェントがモーダルダイアログやメニューを開いた。
  • ポインター入力デバイスが物理的に切断された、またはホバー可能なポインター入力デバイス(例:ホバー可能なペン/スタイラス)がデジタイザで検出可能なホバー範囲から外れた。
  • その後、ユーザーエージェントがページのビューポート操作(例:パンやズーム)にポインターを使用した。詳細は touch-action CSS プロパティのセクションを参照。
    注記
    ユーザーエージェントは複数のポインタータイプ(タッチやペンなど)でパンやズームをトリガーできるため、パンやズーム操作の開始は、異なるポインタータイプを含むさまざまなポインターの抑制につながりうる。
  • [HTML] の ドラッグ&ドロップ処理モデルで定義されるドラッグ操作の開始アルゴリズムの一環として、ドラッグ操作を引き起こしたポインターに対して。
注記

その他、ユーザーエージェントMAY ポインターイベントストリームを抑制するシナリオには、以下が含まれる:

  • ポインターがアクティブな間にデバイスの画面の向きが変更された。
  • ユーザーがデバイスのサポート数を超える同時ポインター入力で操作を試みた。
  • ユーザーエージェントが入力を偶発的なものと解釈した(例:ハードウェアがパームリジェクションをサポートしている)。

これらのシナリオを検出する方法は本仕様の範囲外である。

ユーザーエージェントは、MUST 次の手順を実行して ポインターイベントストリームを抑制しなければならない。

4.1.4 レイアウト変更によって発生する境界イベント

画面表面に対する相対移動があった、またはいずれかのプロパティに変化があったポインティングデバイスは、ポインターイベントの種類で定義されるさまざまなイベントを発火する。静止したポインティングデバイス(画面表面に対して移動せず、いずれのプロパティにも変化がない)に対しては、ポインターのヒットテストターゲットに影響するレイアウト変更の後に、ユーザーエージェントMUST 特定の境界イベントを発火しなければならない。詳細は pointeroverpointerenterpointeroutpointerleave を参照。ユーザーエージェントは、パフォーマンス上の理由(例:ヒットテスト過多や、境界イベントリスナーによるレイアウト変更の多発を避けるため)により、これらの境界イベントの発火を遅延してもMAY

注記
静止したポインティングデバイス(画面表面に対して移動せず、いずれのプロパティにも変化がない)は、pointermove イベントを発火することはない。

4.1.5 tiltX / tiltYaltitudeAngle / azimuthAngle の相互変換

Pointer Events には、トランスデューサの X-Y 平面に対する向きを表現するための相補的な2組の属性が含まれる。すなわち、(元の Pointer Events 仕様で導入された)tiltX / tiltY と、(Touch Events - Level 2 仕様から採用された)azimuthAngle / altitudeAngle である。

特定のハードウェアやプラットフォームに応じて、ユーザーエージェントは画面平面に対するトランスデューサの向きに関して、tiltX / tiltYaltitudeAngle / azimuthAngle のいずれか一方の値のみを受け取る可能性が高い。ユーザーエージェントは、これらの値を相互に変換するために、以下のアルゴリズムをMUST使用しなければならない。

ユーザーエージェントが azimuthAngle / altitudeAngle から tiltX / tiltY を算出する場合、最終的な整数値は Math.round [ECMASCRIPT] の規則に従って丸めるべきである(SHOULD)。

5: tiltX/tiltY と altitudeAngle/azimuthAngle の相互変換
/* 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};
}

4.2 ポインターイベントの種類

以下に本仕様で定義されるイベントタイプを示す。

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

4.2.1 pointerover イベント

ユーザーエージェントは、次のいずれかが発生したとき、MUST pointerover という名前のポインターイベントを発火しなければならない。

4.2.2 pointerenter イベント

ユーザーエージェントは、次のいずれかが発生したとき、MUST pointerenter という名前のポインターイベントを発火しなければならない。

注記
このイベントタイプは pointerover に類似するが、2つの違いがある。pointerenter はバブルしないこと、そしてそのディスパッチでは子孫要素のヒットテスト境界も考慮することである。
注記
このイベントタイプは、[UIEVENTS] で記述される mouseenter イベントや、[CSS21] で記述される CSS の :hover 疑似クラスと類似点がある。pointerleave イベントも参照。

4.2.3 pointerdown イベント

ユーザーエージェントは、ポインターがアクティブボタン状態に入ったとき、MUST pointerdown という名前のポインターイベントを発火しなければならない。マウスでは未押下から少なくとも1つのボタン押下に遷移したとき、タッチではデジタイザに物理的に接触したとき、ペンではボタン未押下のままデジタイザに物理接触したとき、またはホバー中に未押下から少なくとも1つのボタン押下に遷移したときである。

注記
マウス(やその他の複数ボタンのポインターデバイス)では、pointerdown および pointerup は、mousedown および mouseup とまったく同じ状況で発火するわけではない。詳細は 複数ボタンの組み合わせ操作 を参照。

ホバーをサポートしない入力デバイスでは、ユーザーエージェントは、MUST pointerdown をディスパッチする前に、pointerover、続いて pointerenter という名前のポインターイベントも発火しなければならない。

注記
著者は、(isPrimary プロパティが true の場合)一部の互換マウスイベントの発火を、pointerdown イベントをキャンセルすることで防ぐことができる。これにより、そのポインターに PREVENT MOUSE EVENT フラグが設定される。ただし、mouseovermouseentermouseoutmouseleave の発火は防止されない点に注意。

4.2.4 pointermove イベント

ユーザーエージェントは、ポインターが pointerdownpointerup を発火させない種類のプロパティをいずれか変更したとき、MUST pointermove という名前のポインターイベントを発火しなければならない。これには、座標、圧力、接線圧、傾き、ねじれ、接触ジオメトリ(widthheight)、または 組み合わせボタン のいずれかの変化が含まれる。

ユーザーエージェントは、MAY パフォーマンス上の理由などにより、pointermove のディスパッチを遅延してもよい。 この場合、単一のディスパッチ済み pointermove に対して、合成イベント情報は getCoalescedEvents メソッドを通じて公開される。 このようなイベントの最終座標は、イベントのターゲット決定に使用されるべきである。

4.2.5 pointerrawupdate イベント

ユーザーエージェントは、MUST pointerrawupdate という名前のポインターイベントを発火 しなければならず、その発火は セキュアコンテキスト 内に限られる。これは、ポインターが pointerdownpointerup を発火しないプロパティを変更したときである。該当プロパティの一覧は pointermove イベントを参照。

pointermove と対照的に、ユーザーエージェントは pointerrawupdate を可能な限り早く、かつ JavaScript が処理可能な頻度でディスパッチするべきである(SHOULD)。

pointerrawupdatetarget は、pointermove のそれと異なる可能性がある。これは pointermove が遅延または合成され得るためであり、target 決定に用いられるイベントの最終位置が、その合成イベントの位置と異なり得るからである。

同一の pointerId を持ち、まだ イベントループ でディスパッチされていない別の pointerrawupdate がすでに存在する場合、ユーザーエージェントは、新規の pointerrawupdate を新たな タスクとして作成する代わりに、それに合成してもMAY。この結果、pointerrawupdate が合成イベントを持つことがあり、イベントループで処理され次第、それらは1つの pointerrawupdate の合成イベントとしてまとめて配信される。詳細は getCoalescedEvents を参照。

pointerrawupdatepointermove の順序に関して、プラットフォームからの更新が両イベントを引き起こす場合、ユーザーエージェントは、MUST 対応する pointermove より前に pointerrawupdate をディスパッチしなければならない。

target を除けば、最後の pointermove 以降にディスパッチされたすべての pointerrawupdate の合成イベントリストの連結は、次の pointermove の合成イベントと、他のイベント属性に関して同一である。pointerrawupdate の属性は、pointermove とほぼ同じだが、cancelable だけは pointerrawupdate に対して MUST false でなければならない。

ユーザーエージェントは、SHOULD 互換マウスイベントpointerrawupdate に対して発火しないべきである。

注記
pointerrawupdate のリスナーを追加すると、ユーザーエージェントの実装によってはページのパフォーマンスに悪影響を与える可能性がある。大半のユースケースでは他の pointerevent タイプで十分である。pointerrawupdate リスナーは、JavaScript が高頻度イベントを必要とし、同等の速度で処理できる場合にのみ追加すべきである。このような場合、他の種類のポインターイベントをリッスンする必要はおそらくない。

4.2.6 pointerup イベント

ユーザーエージェントは、ポインターがアクティブボタン状態を離れたとき、MUST pointerup という名前のポインターイベントを発火しなければならない。マウスでは少なくとも1つのボタン押下から未押下に遷移したとき、タッチではデジタイザから物理的な接触が離れたとき、ペンではボタン未押下でデジタイザとの物理接触が離れたとき、またはホバー中に少なくとも1つのボタン押下から未押下に遷移したときである。

ホバーをサポートしない入力デバイスでは、ユーザーエージェントは、MUST pointerup をディスパッチした後に、pointerout、続いて pointerleave という名前のポインターイベントも発火しなければならない。

すべての pointerup イベントにおいて、pressure の値は 0 である。

ユーザーエージェントは、ポインターが現在キャプチャされている場合、MUST ポインターキャプチャを暗黙的に解除しなければならない。

注記
マウス(やその他の複数ボタンのポインターデバイス)では、pointerdown および pointerup は、mousedown および mouseup とまったく同じ状況で発火するわけではない。詳細は 複数ボタンの組み合わせ操作 を参照。

4.2.7 pointercancel イベント

ユーザーエージェントは、ポインターイベントストリームを抑制するシナリオを検出したとき、MUST pointercancel という名前のポインターイベントを発火しなければならない。

pointercancel イベントにおける次のプロパティ値は、同じ pointerId を持つ最後にディスパッチされたポインターイベントの値と一致しなければならない(MUST):widthheightpressuretangentialPressuretiltXtiltYtwistaltitudeAngleazimuthAnglepointerTypeisPrimary、および [UIEVENTS] から継承される座標。pointercancel イベントの coalescedEvents および predictedEvents のリストは空でなければならない(MUST)。またイベントの cancelable 属性は false でなければならない(MUST)。

4.2.8 pointerout イベント

ユーザーエージェントは、次のいずれかが発生したとき、MUST pointerout という名前のポインターイベントを発火しなければならない。

4.2.9 pointerleave イベント

ユーザーエージェントは、次のいずれかが発生したとき、MUST pointerleave という名前のポインターイベントを発火しなければならない。

注記
このイベントタイプは pointerout に類似するが、2つの違いがある。pointerleave はバブルしないこと、そしてそのディスパッチでは子孫要素のヒットテスト境界も考慮することである。
注記
このイベントタイプは、[UIEVENTS] で記述される mouseleave イベントや、[CSS21] で記述される CSS の :hover 疑似クラスと類似点がある。pointerenter イベントも参照。

4.2.10 gotpointercapture イベント

ユーザーエージェントは、要素がポインターキャプチャを受け取ったとき、MUST gotpointercapture という名前のポインターイベントを発火しなければならない。このイベントはキャプチャを受ける要素で発火される。以後、そのポインターに関するイベントはこの要素で発火される。ポインターキャプチャの設定保留中のポインターキャプチャの処理 を参照。

4.2.11 lostpointercapture イベント

ユーザーエージェントは、ポインターのキャプチャが解除された後、MUST lostpointercapture という名前のポインターイベントを発火しなければならない。このイベントは、キャプチャが削除された要素で発火される。キャプチャ解除後の、そのポインターに関する後続のイベントは、clickauxclickcontextmenu イベントを除き、(本仕様の範囲外である)通常のヒットテストの仕組みに従ってイベントターゲットが決定される。ポインターキャプチャの解除ポインターキャプチャの暗黙的な解除、および 保留中のポインターキャプチャの処理 を参照。

4.2.12 clickauxclickcontextmenu イベント

このセクションは、[UIEVENTS] で定義される clickauxclickcontextmenu イベントへの追加である。これらのイベントは通常、ユーザーインターフェースのアクティベーションに結びついており、キーボードなどのポインター以外の入力デバイスからでも発火する。

これらのイベントは MUST PointerEvent 型でなければならず、本セクションの残りで述べる追加要件の対象となる。

4.2.12.1 イベント属性

これらのイベントについて、本仕様(この spec)で定義される PointerEvent 固有属性は、pointerIdpointerType を除き、すべてデフォルト値でなければならない(MUST)。加えて:

  • イベントがポインティングデバイスによって生成された場合、それらの pointerIdpointerType は、これらのイベントを引き起こした PointerEvent と同一でなければならない(MUST)。
  • イベントが非ポインティングデバイス(音声認識ソフトウェアやキーボード操作など)によって生成された場合、pointerId-1 でなければならず(MUST)、pointerType は空文字列でなければならない(MUST)。
4.2.12.2 イベント座標

PointerEvent に関して述べたとおり、CSSOM View Module は各種座標プロパティ(screenXscreenYpageXpageYclientXclientYxyoffsetXoffsetY)を double に再定義して、小数座標を許容することを提案している。しかしこの変更を PointerEvent のみに適用し、通常の MouseEvent には適用しない場合、clickauxclickcontextmenu においてレガシーコードとのウェブ互換性の問題を引き起こすことが実証されている。したがって、CSSOM View Module の提案変更を PointerEvent にのみ実装しているユーザーエージェントは、MUST clickauxclickcontextmenu における各座標プロパティを、元の UI Events で定義される long 値に変換しなければならない。その際 Math.floor [ECMASCRIPT] を使用する。

4.2.12.3 イベントのディスパッチ

clickauxclickcontextmenu イベントは、以下のアルゴリズムでイベントターゲットが上書きされる点を除き、[UIEVENTS] 仕様で定義されるディスパッチプロセスにMUST従う。

  1. event をディスパッチ中の clickauxclickcontextmenu イベント、userEventevent の発火を引き起こしたユーザー操作イベントとする。

    注記

    userEventPointerEvent 以外であり得る。例えば、チェックボックス要素でスペースバーを押下して click のディスパッチが行われた場合、それは KeyboardEvent である。

    userEventPointerEvent の場合、userEventclick または auxclick の場合は pointerupcontextmenu の場合は(ネイティブプラットフォームの慣習に依存して)pointerdown または pointerup である。

  2. userEventPointerEvent でない場合、[UIEVENTS] 仕様に従って、event のターゲットを上書きせずにディスパッチし、以下の残りの手順はスキップする。
  3. target を次のように定義する:

    eventcontextmenu である、または対応するポインターがキャプチャされている間に userEvent がディスパッチされた場合、targetuserEvent のターゲットとする。

    それ以外の場合(eventclick または auxclick で、userEvent がキャプチャされずにディスパッチされた pointerup である場合)、target を、event をディスパッチしている時点の DOM における、対応する pointerdownpointerup のターゲットの最も近い共通包括祖先とする。

  4. [UIEVENTS] 仕様に従って、eventtarget にディスパッチする。

    注記
    userEvent がキャプチャされていた場合、同じ lostpointercapture と同一の pointerId のイベントがすでにディスパッチされているとしても、eventuserEvent のキャプチャ先ターゲットにディスパッチされる。

5. Element インターフェースの拡張

次のセクションでは、ポインターキャプチャの設定および解除を容易にするため、既存の Element インターフェースへの拡張について説明する。

WebIDLpartial interface Element {
  undefined setPointerCapture (long pointerId);
  undefined releasePointerCapture (long pointerId);
  boolean hasPointerCapture (long pointerId);
};
setPointerCapture()

引数の pointerId で識別されるポインターについて、ポインターキャプチャを設定し、このメソッドが呼び出された要素にキャプチャする。以後そのポインターのイベントに対しては、キャプチャ先ターゲットが通常のヒットテスト結果を置き換え、ポインターが常にキャプチャ先ターゲット上にあるかのように扱われ、キャプチャが解除されるまで常にこの要素をターゲットにしなければならない(MUST)。このメソッドが有効になるには、ポインターが アクティブボタン状態 にある必要があり、そうでない場合は黙って失敗する。与えられたメソッド引数がいずれのアクティブなポインターとも一致しない場合は、throw を行い、"NotFoundError" の DOMException を投げる。

releasePointerCapture()

引数の pointerId で識別されるポインターについて、ポインターキャプチャを解除し、このメソッドが呼び出された要素から解放する。以後そのポインターのイベントは、イベントターゲットの決定にあたり(本仕様の範囲外である)通常のヒットテストの仕組みに従う。与えられたメソッド引数がいずれのアクティブなポインターとも一致しない場合は、throw を行い、"NotFoundError" の DOMException を投げる。

hasPointerCapture

このメソッドが呼び出された要素が、引数の pointerId で識別されるポインターに対して ポインターキャプチャ を保持しているかどうかを示す。特に、保留中のポインターキャプチャのターゲット上書き が、pointerId に対してこの要素に設定されている場合は true を返し、そうでない場合は false を返す。

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

6. GlobalEventHandlers ミックスインの拡張

次のセクションでは、イベントハンドラーの登録を容易にするため、既存の 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;
};
onpointerover
イベントハンドラー IDL 属性pointerover イベントタイプ用。
onpointerenter
イベントハンドラー IDL 属性pointerenter イベントタイプ用。
onpointerdown
イベントハンドラー IDL 属性pointerdown イベントタイプ用。
onpointermove
イベントハンドラー IDL 属性pointermove イベントタイプ用。
onpointerrawupdate
イベントハンドラー IDL 属性pointerrawupdate イベントタイプ用。
onpointerup
イベントハンドラー IDL 属性pointerup イベントタイプ用。
onpointercancel
イベントハンドラー IDL 属性pointercancel イベントタイプ用。
onpointerout
イベントハンドラー IDL 属性pointerout イベントタイプ用。
onpointerleave
イベントハンドラー IDL 属性pointerleave イベントタイプ用。
ongotpointercapture
イベントハンドラー IDL 属性gotpointercapture イベントタイプ用。
onlostpointercapture
イベントハンドラー IDL 属性lostpointercapture イベントタイプ用。

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

Navigator インターフェースは [HTML] で定義されている。本仕様は、デバイス検出のサポートを提供するために Navigator インターフェースを拡張する。

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

デバイスがサポートする同時タッチ接点の最大数。複数のデジタイザ(例:複数のタッチスクリーン)を備えるデバイスの場合、値は各デジタイザでサポートされる最大接点数の集合の最大値でなければならない(MUST)。

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

注記
maxTouchPoints の値が 0 より大きいことは、ユーザーのデバイスがタッチ入力をサポート可能であることを示すが、ユーザーが必ずしもタッチ入力を使用するという意味ではない。著者は、マウス、ペン、スクリーンリーダーなど、システムに存在しうる他の入力モダリティも考慮するよう注意すべきである。
注記
maxTouchPoints は、コンテンツのインタラクションモデルが現在のハードウェアで認識可能であることを保証するためにしばしば用いられる。性能の低いハードウェアを持つユーザーには UI 上の工夫を提供できる。正確なタッチポイント数が不明なプラットフォームでは、認識が保証される最小数が提供される。そのため、実際に認識されるタッチポイント数が maxTouchPoints の値を上回る可能性がある。

8. 直接操作の挙動の宣言

属性と既定の動作 で述べたように、ビューポートの操作(パンおよびズーム)は、ポインターイベントをキャンセルしても抑止できない。代わりに、著者はどの挙動を許可し、どれを抑止するかを、touch-action CSS プロパティを用いて宣言的に定義しなければならない。

注記
ビューポートの操作に用いられるポインターの問題は一般的にはタッチ入力に限定される(ユーザーの指がコンテンツと相互作用する一方でページのパン/ズームも行えるため)が、特定のユーザーエージェントは他のポインター種別に対しても同種の(直接/間接の)操作を許可する場合がある。例えば、モバイル/タブレット端末では、スタイラスでもスクロールできることがある。歴史的経緯から、本仕様で定義する touch-action CSS プロパティはタッチ入力のみに言及しているように見えるが、実際にはパンやズームのための直接操作を可能にするあらゆるポインター入力に適用される。

8.1 touch-action CSS プロパティ

Name: touch-action
Value: auto | none | [ pan-x || pan-y ] | manipulation
Initial: auto
Applies to: 以下を除くすべての要素:非置換インライン要素、表の行、行グループ、表の列、および列グループ
Inherited: no
Percentages: N/A
Media: visual
Computed value: 指定値と同じ
Canonical order: 文法順
Animation type: アニメーション不可

touch-action CSS プロパティは、(プロパティ名に反してタッチに限定されない)直接操作の相互作用がユーザーエージェントのパンおよびズームの挙動を引き起こしてよいか(MAY)を決定する。touch-action の値のセクションを参照。

パンやズームを開始する直前に、以下のすべての条件が真であれば、ユーザーエージェントMUST ポインターイベントストリームを抑制しなければならない。

注記
一部のユーザーエージェントは、複数の個別なジェスチャーから成るが単一の連続するジェスチャーの一部として扱われる複雑な挙動に対して、複合ジェスチャーを実装している。例えばタッチスクリーンでの「フリックしてスクロール」:ユーザーが素早く指を動かしてパンを開始し、指を離した後もドキュメントが慣性でスクロールを続ける、といったケース。この間にユーザーが再度指を置いて別の「フリック」を行い、パンの勢いを増したり、現在のパンに対抗して減速/停止/反転させたりできる。本仕様はジェスチャーや挙動の実装方法を規定しないため、2 回目のタッチが(2 回目の「フリック」や現在のパンに対する対抗として解釈される前に)ポインターイベントを発火するかどうかはユーザーエージェントに委ねられる。
注記
touch-action は、埋め込みのブラウジングコンテキストには適用/カスケードしない。例えば、<iframe>touch-action を適用しても、<iframe> 内部のパン/ズームに関する直接操作の挙動には影響しない。

8.2 サポートされる直接操作の挙動の判定

ユーザーが直接操作ポインター(タッチスクリーンのタッチやスタイラスなど)で要素と相互作用する場合、その入力の効果は、以下のように、touch-action プロパティの値と、当該要素およびその祖先の既定の直接操作の挙動によって決定される。

注記
一部のユーザーエージェントは、複数の同時ポインター(例:マルチタッチ)によるパンおよびズームの相互作用をサポートする。複数の同時ポインターの touch-action 値を処理または関連付ける方法は本仕様の範囲外である。

8.3 touch-action の値の詳細

touch-action プロパティは、ビューポートのパンおよびズームに関連する直接操作の挙動を対象とする。テキスト選択/ハイライト、リンクやフォームコントロールのアクティベーションなど、その他のユーザーエージェントの挙動は、この CSS プロパティによって影響を受けてはならない(MUST NOT)。

注記
「パン」と「スクロール」は同義と見なされる(より正確には、「パン」は直接操作入力による「スクロール」)。パン/スクロールや、autonone の値に対する挙動を引き起こすための相互作用/ジェスチャーの定義は本仕様の範囲外である。
auto
ユーザーエージェントは、当該要素上で始まるビューポートのパンおよびズームに関連する許可された直接操作の挙動を考慮してもよい(MAY)。
none
当該要素上で始まる直接操作の相互作用は、ビューポートのパンおよびズームに関連する挙動を引き起こしてはならない(MUST NOT)。
pan-x
pan-y
ユーザーエージェントは、当該要素上で始まる直接操作の相互作用のうち、列挙された値のすべてで指定された方向のいずれかで開始するパンに限って考慮してもよい(MAY)。パンが開始された後は、たとえ逆方向から開始するパンが不許可であっても、ユーザーは方向を反転できる。対照的に、(pan-x または pan-y により)パンが単一の軸に制限されている場合、パン中に軸を変更することはできない。
manipulation
ユーザーエージェントは、当該要素上で始まる直接操作の相互作用のうち、パンと連続的なズーム(ピンチズームなど)の目的に限り考慮してもよい(MAY)。一方、一定時間内に複数回のアクティベーションを必要とするその他の関連挙動(ダブルタップでズーム、ダブルタップ長押しによる片手ズームなど)を引き起こしてはならない(MUST NOT)。
注記
実装で一般的な追加の touch-actionは、[COMPAT] で定義されている。
注記
touch-action プロパティは、CSS の width および height プロパティの両方をサポートする要素にのみ適用される([CSS21] 参照)。この制限は、低レイテンシ直接操作によるパンおよびズームのためのユーザーエージェント最適化を容易にするために設計されている。既定でサポートされない要素(非置換インライン要素である <span> など)については、著者は display CSS プロパティを block など widthheight をサポートする値に設定できる。将来の仕様ではこの API をすべての要素に拡張することがありうる。
注記

方向別の pan 値は、一部のオーバースクロール挙動のカスタマイズに有用である。例えば、簡易なプル・トゥ・リフレッシュを実装するには、ドキュメントの touch-action を、スクロール位置が 0 のときは pan-x pan-down、それ以外は pan-x pan-y に設定できる。これにより、ドキュメントの先頭から開始する上方向のパン/スクロールに対して、ポインターイベントハンドラーで挙動を定義できる。

方向別の pan 値は、ネイティブにスクロールする要素内でポインターイベント処理によりカスタムパンを実装するコンポーネント(あるいはその逆)を構成するためにも使える。例えば、画像カルーセルは pan-y を用いて、ドキュメントの垂直パンに干渉せずに、水平方向のパン操作に対するポインターイベントを確実に受け取れるようにできる。カルーセルが最右端に到達したときは、touch-actionpan-y pan-right に変更し、可能であればその後の範囲外のスクロール操作でビューポート内のドキュメントをスクロールできるようにする。なお、パン/スクロールの操作が進行中に、その挙動を変更することはできない。

注記
パンやズームに関する一部の既定の直接操作の挙動を無効化すると、他の挙動に対してユーザーエージェントがより迅速に応答できる場合がある。例えば、auto の場合、多くのユーザーエージェントはダブルタップのジェスチャー処理のために click の前に通常 300ms の遅延を加える。このような場合、touch-action: none または touch-action: manipulation を明示的に設定すると、この遅延は解消される。なお、タップやダブルタップのジェスチャーを判定する方法は本仕様の範囲外である。
Example 6: すべての直接操作の挙動を不許可にする
<div style="touch-action: none;">
    This element receives pointer events for all direct manipulation interactions that otherwise lead to panning or zooming.
</div>
Example 7: 水平パンのみを許可する
<div style="touch-action: pan-x;">
    This element receives pointer events when not panning in the horizontal direction.
</div>
Example 8: パンとズームの直接操作の挙動を不許可にする子領域
<div style="overflow: auto;">
    <div style="touch-action: none;">
        This element receives pointer events for all direct manipulation interactions that otherwise lead to panning or zooming.
    </div>
    <div>
        Direct manipulation interactions on this element MAY be consumed for manipulating the parent.
    </div>
</div>
Example 9: パンとズームの直接操作の挙動を不許可にする中間の親
<div style="overflow: auto;">
    <div style="touch-action: pan-y;">
        <div style="touch-action: pan-x;">
            This element receives pointer events for all direct manipulation interactions because
            it allows only horizontal panning yet an intermediate ancestor
            (between it and the scrollable element) only allows vertical panning.
            Therefore, no direct manipulation behaviors for panning/zooming are
            handled by the user agent.
        </div>
    </div>
</div>

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

9.1 導入

このセクションは参考であり、規範的ではない。

ポインターキャプチャを用いると、特定のポインターに関するイベント(互換マウスイベントを含む)を、通常のポインター位置のヒットテスト結果とは異なる特定の要素へリターゲットできる。これは、カスタムスライダーコントロール(例えば [HTML] の <input type="range"> コントロールに類似)などの場面で有用である。スライダーのつまみ要素にポインターキャプチャを設定することで、ポインターがつまみから外れても、ユーザーはコントロールを前後にスライドできる。

カスタム音量スライダー
Figure 6 つまみ要素を前後にスライドして値を選択するカスタムスライダーの例。つまみに対して pointerdown が行われた後、ポインターキャプチャを用いると、ポインターがつまみから外れてもスライドできる。

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

ポインターキャプチャは、Element 型の element に対して element.setPointerCapture(pointerId) メソッドを呼び出すことで設定される。 このメソッドが呼び出されたとき、ユーザーエージェントは以下の手順をMUST 実行する。

  1. メソッド引数として提供された pointerId が、いずれのアクティブなポインターにも一致しない場合、throw を行い、"NotFoundError" の DOMException を投げる。
  2. 与えられた pointerId に対応する アクティブなポインターpointer とする。
  3. element が [DOM] の接続済みでない場合、throw を行い、"InvalidStateError" の DOMException を投げる。
  4. このメソッドが、element の [DOM] のノードドキュメントにロックされた要素([PointerLock] の pointerLockElement)が存在する間に呼び出された場合、throw を行い、"InvalidStateError" の DOMException を投げる。
  5. pointerアクティブボタン状態 にない、または elementノードドキュメントpointerアクティブドキュメント でない場合、これらの手順を終了する。
  6. 指定された pointerId について、保留中のポインターキャプチャのターゲット上書きを、このメソッドが呼び出された Element に設定する。
注記
保留状態にある以前の設定/解除呼び出しの最中に、ポインターキャプチャの設定または解除を行う呼び出しが行われた場合(保留中のポインターキャプチャの処理 を参照)、後からの呼び出しが成功すれば前の呼び出しを上書きし、そうでなければ前の呼び出しが有効のままとなる。これは、暗黙のポインターキャプチャpointerdown リスナーで解除しようとして失敗した場合にも当てはまる。

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

ポインターキャプチャは、要素に対して element.releasePointerCapture(pointerId) メソッドを明示的に呼び出すことで解除される。このメソッドが呼び出されたとき、ユーザーエージェントは以下の手順をMUST 実行する。

  1. メソッド引数として提供された pointerId が、いずれのアクティブなポインターにも一致せず、かつこれらの手順がポインターキャプチャの暗黙的な解除の結果として呼び出されていない場合、throw を行い、"NotFoundError" の DOMException を投げる。
  2. 指定された pointerId に対し、当該 ElementhasPointerCapture が false の場合、これらの手順を終了する。
  3. 指定された pointerId について、設定されていれば 保留中のポインターキャプチャのターゲット上書きをクリアする。
注記
セクション ポインターキャプチャの設定 の注記を参照。

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

パンおよびズームの直接操作の相互作用を実装する入力(タッチスクリーンでのタッチやスタイラスなど)は、setPointerCapture が、任意の pointerdown リスナーの呼び出し直前にターゲット要素で呼ばれたかのように、正確に振る舞うべきである(SHOULD)。例えば(pointerdown リスナー内などで)hasPointerCapture API を用いて、これが行われたかどうかを判定できる。次のポインターイベントが発火する前に当該ポインターに対して releasePointerCapture が呼ばれない場合、キャプチャが有効であることを示す gotpointercapture イベントが(通常どおり)ターゲットにディスパッチされる。

注記
これは [PointerEvents] からの破壊的変更だが、既存のコンテンツの大多数には影響しない。典型的なプラットフォーム UX の慣習に合致することに加え、暗黙のキャプチャのこの設計により、ユーザーエージェントはヒットテストを明示的に開発者がオプトインしない限り、タッチ移動イベントで呼び出す必要をなくすパフォーマンス最適化(既存の主要なネイティブ/ウェブ API のタッチ入力におけるパフォーマンス特性と一致)を実現できる。
注記
加えて、ユーザーエージェントは、特定の UI ウィジェット(入力レンジコントロールなど)に対し、すべての入力デバイスで暗黙のポインターキャプチャ挙動を実装してもよい(相互作用の間、フォームコントロール自体の外にある程度指がはみ出すことを許容する)。

9.5 ポインターキャプチャの暗黙的な解除

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

ポインターキャプチャのターゲット上書き が [DOM] の接続済みでなくなった場合、 ポインターキャプチャのターゲット上書き はドキュメントに設定されるべきである(SHOULD)。

保留中のポインターキャプチャのターゲット上書き が [DOM] の接続済みでなくなった場合、 保留中のポインターキャプチャのターゲット上書き ノードはクリアされるべきである(SHOULD)。

注記
直前の 2 つの段落の結果として、キャプチャされたポインターに対応する lostpointercapture イベントが、 キャプチャノードが削除された後、次回の 保留中のポインターキャプチャの処理 の際にドキュメントで発火される。

要素に対してポインターロック([PointerLock])が正常に適用された場合、ユーザーエージェントは、いずれかの要素がキャプチャ中もしくはキャプチャ予定であるなら、releasePointerCapture メソッドが呼ばれたかのように手順を実行しなければならない(MUST)。

10. 合成イベントと予測イベント

注記
本仕様は、ユーザーエージェントがポインター移動データをどのように合成(coalesce)または予測するかを定義しない。ここでは、この情報へアクセスするための API のみを規定する。

10.1 合成イベント

パフォーマンス上の理由から、ユーザーエージェントはポインターのpointermoveイベントを、ポインターの測定可能プロパティ (座標、圧力、接線圧、傾き、ねじれ、接触ジオメトリなど)が更新される度に必ずしも送信しない選択を行うかもしれない。代わりに複数の変化を 1 つの pointermove または pointerrawupdate イベントに合成(結合/統合)する場合がある。この手法は ユーザーエージェントMUST 行うイベント処理量を減らすのに役立つ一方で、特に高速かつ大きな移動においてポインター位置追跡の粒度と忠実度を低下させる。getCoalescedEvents メソッドを用いることで、アプリケーションは未合成の生の位置変化へアクセスでき、より精密なポインター移動データ処理が可能となる。例えば描画アプリケーションでは、未合成イベントを用いてポインターの実際の動きにより近い滑らかな曲線を描画できる。

曲線の拡大図。合成済みと未合成ポイントの比較
Figure 7 描画アプリケーションにおける曲線の例 — pointermove イベントの合成済み座標(灰色の点)のみを使うと、線は角ばってギザギザになる;getCoalescedEvents() が提供するより細かいポイント(赤い円)で同じ線を描画すると、ポインター移動をより滑らかに近似できる。

PointerEvent は関連付けられた 合成イベントリスト(0 個以上の PointerEvent のリスト)を持つ。信頼できる(trusted) pointermove および pointerrawupdate イベントの場合、このリストはそのイベントへ合成されたすべての PointerEvent の列である。信頼できる「親」pointermovepointerrawupdate イベントはこれら合成イベントの蓄積結果を表すが、(ディスプレイのリフレッシュレートに合わせるなど)追加処理を含む場合がある。その結果、これらイベントの合成イベントリストには常に少なくとも 1 つのイベントが含まれる。その他のすべての信頼できるイベントタイプでは空リストとなる。信頼されない(untrusted)イベントでは、合成イベントリストはコンストラクタに渡された値で初期化される。

注記
信頼できる親イベントは合成イベントの要約/集約であるため、開発者は親イベントかすべての合成イベントかのどちらか一方のみを処理すればよく、両方を処理する必要はない。
注記
信頼できるイベント(合成イベントリストを含む)が JavaScript から再ディスパッチされた場合、イベントディスパッチアルゴリズムはイベントの isTrusted ビットを false に設定するが、合成イベントリスト内の同一ビットは元の true のまま変更されない。

信頼できるイベントの合成イベントリスト内のイベントは以下を持つ:

Example 10: 合成イベントリストを利用する基本的なキャンバス描画アプリ
<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>
注記
PointerEvent の属性は、合成イベントリスト内のイベントを最も適切に表現できるよう初期化される。ユーザーエージェントがこれを行う具体的手順は本仕様では扱わない。

これらディスパッチされたイベントの順序は、元のイベントの実際の順序と一致していなければならない(MUST)。例えば、ある pointerdown イベントが合成 pointermove イベント群のディスパッチを引き起こす場合、ユーザーエージェントはまずその pointerId の合成イベントをすべて含む 1 つの pointermove イベントをディスパッチし、その後で 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 件

10.2 予測イベント

一部のユーザーエージェントには、確定したポインター移動の一連の後で、現在のジェスチャーにおける直前のイベントや移動の速度/軌道に基づき、将来のポインター移動の位置を予測できるアルゴリズムが組み込まれている。アプリケーションはこの情報を getPredictedEvents メソッドで利用し、知覚遅延を減らすために先読み描画を行い、実際のポイントが到着したら予測ポイントを破棄できる。

合成ポイントで描画された線と、将来の予測ポイント
Figure 8 描画アプリケーションの線の例(左下から右上へのジェスチャー結果)。pointermove イベントの合成座標に加え、ユーザーエージェントの予測する将来ポイント(灰色の円)を表示。

PointerEvent は関連付けられた 予測イベントリスト(0 個以上の PointerEvent のリスト)を持つ。信頼できる pointermove イベントでは、ユーザーエージェントが将来続くと予測する PointerEvent の列である。その他の信頼できるイベントタイプでは空リストとなる。信頼されないイベントでは、予測イベントリストはコンストラクタに渡された値で初期化される。

注記

pointerrawupdate イベントは非空の 合成イベントリスト を持つ場合があるが、パフォーマンス上の理由からその 予測イベントリスト は通常空である。

注記
信頼できるイベント(予測イベントリストを含む)が JavaScript から再ディスパッチされた場合、イベントディスパッチアルゴリズムはイベントの isTrusted ビットを false に設定するが、予測イベントリスト内の同一ビットは元の true のまま変更されない。

リスト内のイベント数と現在のタイムスタンプからどれだけ未来かは、ユーザーエージェントとその使用する予測アルゴリズムによって決定される。

信頼できるイベントの予測イベントリスト内のイベントは以下を持つ:

注記

著者は予測イベントを、次のポインターイベントがディスパッチされるまで有効な予測としてのみ扱うべきである。ユーザーエージェントがどれだけ未来を予測するかによっては、通常のポインターイベントが予測イベントのタイムスタンプより前にディスパッチされる可能性がある。

Example 11: 合成イベントと予測イベントを用いた描画の概念的アプローチ

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);
    }
});

10.3 合成イベントリストと予測イベントリストの充填および維持

信頼できる PointerEvent が生成されたとき、ユーザーエージェントは、合成イベントリスト および 予測イベントリスト の各イベントに対して以下の手順を実行すべきである(SHOULD)。

  1. イベントの pointerIdpointerTypeisPrimaryisTrusted を「親」ポインターイベントの対応するプロパティに一致させる。
  2. イベントの cancelable および bubbles を false に設定(これらイベントは単独でディスパッチされることがないため)。
  3. イベントの 合成イベントリスト および 予測イベントリスト を空リストに設定。
  4. その他すべての属性を既定の PointerEvent 値に初期化する。

信頼できる PointerEventtarget が変更されたとき、ユーザーエージェントは 合成イベントリスト および 予測イベントリスト の各イベントに対し以下を実行すべきである(SHOULD)。

  1. イベントの target を親ポインターイベントの target と一致させる。

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

現在存在するウェブコンテンツの大多数は Mouse Events のみを対象に記述されている。以下では、ユーザーエージェント がこのコンテンツとの互換性のために汎用ポインター入力をマウスイベントへマッピングする方法のアルゴリズムを説明する(MAY)。

マウスイベントとの互換マッピングは本仕様の任意(OPTIONAL)機能である。ユーザーエージェントは既存のレガシーコンテンツとの互換性を最大化するため、この機能をサポートすることが推奨される。

注記

高レベルでは、互換マウスイベントは対応するポインターイベントと「インターリーブ」されることを意図している。しかし、この具体的な順序は必須ではなく、互換マウスイベントを実装するユーザーエージェントは、相対順序が一貫している限り、マウスイベントのディスパッチを遅延またはグループ化してもよい(MAY)。

特にタッチスクリーン入力の場合、ユーザーエージェントは(著者が touch-action により明示的に抑止しない限り)ジェスチャー認識のため追加のヒューリスティクスを適用するかもしれない。pointerdown から pointerup までのイベント列において、ジェスチャー認識はジェスチャーの検出/無視のため pointerup まで待機する必要がある場合がある。その結果、相互作用が特定のジェスチャーを意図していないと判断された場合は、シーケンス全体の互換マウスイベントが最後の pointerup イベント後にまとめてディスパッチされる可能性がある。これらジェスチャー認識の詳細は本仕様で定義されず、実装間で差異がありうる。

互換マウスイベントへの対応に関係なく、ユーザーエージェントは常に clickauxclickcontextmenu イベントをサポートしなければならない(MUST)。これらのイベントは PointerEvent 型であり、互換マウスイベント ではないためである。ポインターイベント中に preventDefault を呼び出しても、clickauxclickcontextmenu が発火するかどうかには影響を与えてはならない(MUST NOT)。

注記

一部高レベルイベント(contextmenufocusblur など)のポインターイベントとの相対順序は未定義であり、ユーザーエージェント間で異なる。例えば、あるユーザーエージェントでは contextmenupointerup の後に続くことが多い一方、別のユーザーエージェントでは pointeruppointercancel に先行する場合があり、状況によっては対応するポインターイベントなしに(キーボード操作などの結果として)発火することもある。

さらに、ユーザーエージェントは clickauxclickcontextmenu イベントを発火すべきかどうかを判断する独自のヒューリスティクスを適用する場合がある。同種の他の(非プライマリ)ポインターや別タイプの他のプライマリポインターが存在する場合、これらイベントを発火しない選択をすることがある。また、指の接触中に過度の移動が含まれるなど「クリーン」なタップ/クリック/長押しと見なされない行為について、clickauxclickcontextmenu を発火しない場合がある。これらユーザーエージェントの挙動は本仕様で定義されず、実装間で差異がありうる。

特に断りがない限り、マッピングされた任意のマウスイベントのターゲットは、対象のポインターイベントと同一であるべきである(SHOULD)。ただしターゲットがもはやその ownerDocument のツリーに参加していない場合は、マウスイベントは当該ターゲットがツリーから除去された時点での最も近い祖先ノード(依然として ownerDocument のツリーに参加している)で発火されるべきであり、そのノードに基づく新しいイベントパスがマウスイベント用に構築される。

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

マウスイベントはポインターが押下状態(down)のときのみ防ぐことができる。ホバー中のポインター(例:ボタン未押下のマウス)はそのマウスイベントを防止できない。

mouseovermouseoutmouseentermouseleave イベントは(ポインターが押下状態でも)決して防止されない。

互換マウスイベントは、ポインターイベントの EventListenerpassive [DOM] に設定されている場合は防止できない。

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

プライマリポインター のみが互換マウスイベントを生成できるが、複数のプライマリポインター が同時にアクティブとなり、それぞれが独自の互換マウスイベントを生成する場合がある。MouseEvents に依存するスクリプトとの互換性のため、マウス遷移イベント(mouseovermouseoutmouseentermouseleave)は単一のレガシーマウス入力の移動をシミュレートすべきである(SHOULD)。これは、すべてのイベントターゲットにおける出入り状態が [UIEVENTS] に従って妥当であることを意味する。ユーザーエージェントは、ドキュメント内で レガシーマウスポインターの有効位置 を以下のように維持することでこれを保証すべきである(SHOULD)。

pointerdownpointeruppointermove イベント、または window での pointerleave イベントを発火する直前に、ユーザーエージェントは以下の手順を実行すべきである(SHOULD)。

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

レガシーマウスポインターの有効位置 は、ポインター遷移イベント(pointeroverpointeroutpointerenterpointerleave)と対応するレガシーマウス遷移イベント(mouseovermouseoutmouseentermouseleave)を常に直接 1 対 1 でマッピングできるわけではないことを表す。次のアニメーションは、単一のレガシーマウス入力で 2 つのプライマリポインターを調停するために、ユーザーエージェントがポインター遷移イベントより多くのレガシーマウス遷移イベントをディスパッチする必要があるケースを示す。

Figure 9 同時発生するマウスポインター(白いカーソル)とタッチポインター(白い「手」カーソル)が、単一のレガシーマウス入力(オレンジのカーソル)を 2 つのポインター間で移動させる例。

このアニメーションでは、マウスクリックとタッチタップの間の時間に着目すると、ボタン 1 は pointerout を受け取らない(「実際の」マウスポインターがその期間中にボタン矩形を離れていないため)が、タッチタップで レガシーマウスポインターの有効位置 がボタン 2 へ移動した際には mouseout を受け取る。同様に、タッチタップとマウスがボタン 1 を離れる直前の間、ボタン 1 は同じ理由で pointerover を受け取らないが、レガシーマウスポインターの有効位置 が再びボタン 1 内に戻った際 mouseover を受け取る。

11.2 ホバーをサポートするデバイスのマッピング

ユーザーエージェントがホバーをサポートするデバイスのポインターイベントをディスパッチする際は、以下の手順を実行すべきである(SHOULD)。

  1. ディスパッチ対象のポインターイベントの isPrimary プロパティが false の場合、ポインターイベントをディスパッチして手順を終了する。
  2. ディスパッチ対象のポインターイベントが pointerdownpointeruppointermove イベント、または window での pointerleave イベントなら、レガシーマウスポインターの有効位置の追跡 で述べる互換マウス遷移イベントをディスパッチする。
  3. ポインターイベントをディスパッチする。
  4. ディスパッチされたポインターイベントが pointerdown で、イベントが キャンセル された場合、当該 pointerType に対して PREVENT MOUSE EVENT フラグを設定する。
  5. PREVENT MOUSE EVENT フラグが当該 pointerType に設定されていない場合、かつディスパッチされたポインターイベントが以下のいずれかであれば:
  6. ディスパッチされたポインターイベントが pointerup または pointercancel の場合、当該 pointerTypePREVENT MOUSE EVENT フラグをクリアする。

11.3 ホバーをサポートしないデバイスのマッピング

多くのタッチスクリーンのように、アクティブ状態でない間に座標(または座標集合)をホバーできないデバイスがある。既存の多くのマウスイベント向けコンテンツは入力としてマウスを仮定し、一般に以下が成り立つ:

注記
ホバーは、マウス用に設計されたコンテンツ内で UI 要素の表示/非表示切り替え(例:「ホバーメニュー」)に用いられることがある。この種のコンテンツはしばしば ホバーをサポートしないデバイス と互換性がない。本仕様はこのシナリオとの互換性のためのマッピングや挙動を定義しない。将来の版で検討される。

これにより、この種の入力デバイスに対してユーザーエージェントは異なるマッピングを提供する必要がある。ユーザーエージェントが ホバーをサポートしない デバイスのポインターイベントをディスパッチする際は、以下の手順を実行すべきである(SHOULD)。

  1. ディスパッチ対象のポインターイベントの isPrimaryfalse の場合、ポインターイベントをディスパッチして終了。
  2. ディスパッチ対象のポインターイベントが pointerover で、当該ポインターの pointerdown がまだディスパッチされていない場合、mousemove を発火(レガシーなマウス特化コードとの互換性のため)。
  3. ディスパッチ対象のポインターイベントが pointerdownpointeruppointermove、または window での pointerleave なら、レガシーマウスポインターの有効位置の追跡 に従って互換マウス遷移イベントをディスパッチ。
  4. ポインターイベントをディスパッチ。
  5. ディスパッチされたポインターイベントが pointerdown でイベントが キャンセル された場合、当該 pointerTypePREVENT MOUSE EVENT フラグを設定。
  6. PREVENT MOUSE EVENT フラグが設定されていない場合、かつディスパッチされたポインターイベントが以下なら:
  7. ディスパッチされたポインターイベントが pointerup または pointercancel の場合、当該 pointerTypePREVENT MOUSE EVENT フラグをクリア。

ユーザーエージェントが [TOUCH-EVENTS] で定義される Touch Events と Pointer Events の両方をサポートする場合、ユーザーエージェント は、本セクションで述べられる互換マウスイベントと [TOUCH-EVENTS] に記載される フォールバックマウスイベント の双方を生成してはならない(MUST NOT)。

注記

ホバーをサポートしないデバイス(例:タッチスクリーン上の単一指)によるプライマリポインターで要素をアクティベート(click)する場合、典型的なイベントシーケンスは次のとおり:

  1. mousemove
  2. pointerover
  3. pointerenter
  4. mouseover
  5. mouseenter
  6. pointerdown
  7. mousedown
  8. 移動に応じて 0 回以上の pointermove および mousemove
  9. pointerup
  10. mouseup
  11. pointerout
  12. pointerleave
  13. mouseout
  14. mouseleave
  15. click

ただし、この相互作用中に pointerdown イベントが キャンセル された場合、イベントシーケンスは次のようになる:

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

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

この付録では、Pointer Events の実装におけるセキュリティおよびプライバシーに関する考慮事項を論じる。ここでの議論は、本仕様で定義されるイベントモデル、API、およびイベントの実装から直接生じるセキュリティとプライバシーの問題に限定する。

本仕様で定義される多くのイベント型は、ユーザーの操作に応じてディスパッチされる。これは、悪意のあるイベントリスナーが、ユーザーが通常は機密と考える情報(たとえば、ページと対話中のユーザーのマウス/スタイラス/指の正確な経路/動き)へアクセスできる可能性を生む。

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

このセンサーのデータや、使用された入力機構(マウス、タッチ、ペン)の種類を判別できる能力は、ユーザー、またはユーザーのデバイスや環境の特性を推測するために用いられる可能性がある。推測された特性や、デバイス/環境に関するあらゆる情報自体が機微なものである場合がある — たとえば、悪意のあるサイトがユーザーが支援技術を使用しているかどうかをさらに推測できてしまう可能性がある。この情報は、ユーザープロファイルの構築や、特定のユーザーを「フィンガープリント」して追跡する目的に使用され得る。

緩和策として、ユーザーエージェントは、特定のセンサーデータ(角度、傾き、圧力など)へのアクセスをユーザーが無効化できる機能を含めること、またはユーザーの明示的なオプトイン後にのみ利用可能にすることを検討してもよい。

センサーの工場校正情報は、センサーデータの特有の変動や特性に基づき、個々のデバイスをフィンガープリントするために使用され得る。本仕様では多くのセンサー関連イベント属性を floatdouble の精度で定義しているが、実装では実用上有用な精度に公開するセンサーデータを制限することを推奨する:

本仕様は、著者が「予測イベント」へアクセスできる方法を定義するが、ユーザーエージェントが予測に用いるアルゴリズム自体は定義しない。仕様策定者は、これらのアルゴリズムが、ユーザーが現在実行中のジェスチャーに関連する直前のポインターイベントのみに依拠することを想定している。ユーザーエージェントは、予測アルゴリズムの具体的な実装が、ユーザーに関する機微な情報を明らかにしたり、ユーザーを「フィンガープリント」して追跡するために使用され得る、異なるサイト間でのユーザーの完全な操作履歴のような追加データに依拠しないことを確実にする責任を負う。

これらの考慮事項に加えて、ワーキンググループは本仕様が次のとおりであると考える:

13. 用語集

このセクションは参考であり、規範的ではない。

アクティブボタン状態
buttons プロパティの値が 0 以外であるときのポインターの状態。マウスでは、少なくとも 1 つのボタンが押下されているとき。タッチでは、デジタイザに物理的に接触しているとき。ペンでは、ペンがデジタイザに物理接触しているとき、またはホバー中に少なくとも 1 つのボタンが押下されているとき。
アクティブドキュメント
アクティブなポインターについて、そのポインターから最後のイベントを受け取ったドキュメント。
アクティブなポインター
イベントを生成できる任意のタッチ接触、ペン/スタイラス、マウスカーソル、その他のポインター。特定のポインター(ユニークな pointerId で識別)について、ドキュメント内で追加のイベントを生成できる可能性がある場合、そのポインターは引き続きアクティブと見なされる。例:
  • デバイスに接続されたマウスは常にアクティブである。
  • スクリーン上のタッチ接触はアクティブと見なされる。
  • タッチ接触やペン/スタイラスがデジタイザの検出範囲外に持ち上げられた場合、それはもはやアクティブとは見なされない。
注記
プラットフォームによっては、アクティブなポインターの集合に、ユーザーエージェントをターゲットとしない(他のアプリケーションをターゲットとする)入力も含め、デバイスへのすべてのポインター入力が含まれることがある。
キャンセルされたイベント
preventDefault() の使用、イベントハンドラーで false を返すこと、または [UIEVENTS] および [HTML] で定義されるその他の手段によって既定の動作が防止されたイベント。
接触ジオメトリ
デジタイザ上の入力(最も一般的にはタッチ)のバウンディングボックス。これは通常、単一ピクセルよりも粗いポインター入力解像度を持つデバイスを指す。一部のデバイスはこのデータをまったく報告しない。
デジタイザ
表面が接触中および/または近傍の入力を検出できる種類の入力検知デバイス。最も一般的には、タッチ接触やペン/スタイラスからの入力を検知する表面を指す。
直接操作
特定のユーザーエージェント(たとえばタッチスクリーンデバイス上のブラウザー)は、「直接操作」のメタファーを実装しており、ポインターがコントロールと相互作用するだけでなく、現在のページを直接パンまたはズームするためにも用いられ、直接的な物理接触の錯覚を与える。例として、タッチスクリーンデバイスのユーザーは一般に、指やスタイラスを使ってページを「つかみ」、ポインターを動かすことでパンでき、ページを直接操作できる。これに対し、通常のデスクトップ/ラップトップのマウスカーソルでは、ページを「ドラッグ」するのではなくスクロールバーを使用してパンを行う。
注記
場合によっては、(ラップトップで見られるような)タッチパッドはユーザーがタッチパッド上を「ドラッグ」することでスクロールを可能にする。しかし、これは一般的にタッチパッドが「擬似的」なマウスホイールイベントを生成することによって実現されるため、直接操作には該当しない。
ヒットテスト
ユーザーエージェントがポインターイベントのターゲット要素を決定する過程。通常、ポインターの位置およびドキュメントの画面メディア上の要素の視覚的レイアウトを考慮して決定される。
測定可能プロパティ

測定可能プロパティは、実数または広い領域からの整数で表現される、連続的なポインターセンサーデータに関連する値を表す。ポインターイベントにおいては、widthheightpressuretangentialPressuretiltXtiltYtwistaltitudeAngleazimuthAngle、および [UIEVENTS] のマウスイベントモデルのプロパティ screenXscreenYclientXclientY が測定可能プロパティである。

これに対し、pointerIdpointerTypeisPrimary、および [UIEVENTS] のマウスイベントモデルのプロパティ buttonbuttonsctrlKeyshiftKeyaltKeymetaKey は、センサーデータに関連しないため、測定可能プロパティとは見なされない。

ポインター
マウス、ペン、タッチ接触など、画面上の特定の座標(または座標集合)をターゲットにできる入力デバイスの、ハードウェアに依存しない表現。

A. 謝辞

本ドキュメントに取り入れられているものも含め、多くの提案および推奨をいただいた多くの方々に深く感謝する。グループの議長は、以下の過去および現在のグループメンバーおよび参加者の貢献をここに認める: 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.

本モデルの初版の開拓に尽力された方々、とりわけ次の方々に特別な感謝を捧げる:Charu Chandiram、Peter Freiling、Nathan Furtwangler、Thomas Olsen、Matt Rakow、Ramu Ramanathan、Justin Rogers、 Jacob Rossi、Reed Townsend、Steve Wright。

B. 変更履歴

このセクションは参考であり、規範的ではない。

以下は、本仕様の各版の公開間における、[PointerEvents2] 仕様に対する重大かつ主要な編集上の変更の非規範的な要約である。 本仕様のエディターズドラフトの完全な変更履歴も参照のこと。

C. IDL 索引

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;
    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;
    [SecureContext] sequence<PointerEvent> getCoalescedEvents();
    sequence<PointerEvent> getPredictedEvents();
};

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;
};

D. 参考文献

D.1 規範的参照

[CSS-OVERFLOW-3]
CSS Overflow Module Level 3. Elika Etemad; Florian Rivoal. W3C. 7 October 2025. W3C Working Draft. URL: https://www.w3.org/TR/css-overflow-3/
[CSS21]
Cascading Style Sheets Level 2 Revision 1 (CSS 2.1) Specification. Bert Bos; Tantek Çelik; Ian Hickson; Håkon Wium Lie. W3C. 7 June 2011. W3C Recommendation. URL: https://www.w3.org/TR/CSS2/
[CSSOM-VIEW]
CSSOM View Module. Simon Fraser; Emilio Cobos Álvarez. W3C. 16 September 2025. W3C Working Draft. URL: https://www.w3.org/TR/cssom-view-1/
[DOM]
DOM Standard. Anne van Kesteren. WHATWG. Living Standard. URL: https://dom.spec.whatwg.org/
[ECMASCRIPT]
ECMAScript Language Specification. Ecma International. URL: https://tc39.es/ecma262/multipage/
[HTML]
HTML Standard. Anne van Kesteren; Domenic Denicola; Dominic Farolino; Ian Hickson; Philip Jägenstedt; Simon Pieters. WHATWG. Living Standard. URL: https://html.spec.whatwg.org/multipage/
[infra]
Infra Standard. Anne van Kesteren; Domenic Denicola. WHATWG. Living Standard. URL: https://infra.spec.whatwg.org/
[PointerLock]
Pointer Lock. Vincent Scheib. W3C. 27 October 2016. W3C Recommendation. URL: https://www.w3.org/TR/pointerlock/
[RFC2119]
Key words for use in RFCs to Indicate Requirement Levels. S. Bradner. IETF. March 1997. Best Current Practice. URL: https://www.rfc-editor.org/rfc/rfc2119
[RFC8174]
Ambiguity of Uppercase vs Lowercase in RFC 2119 Key Words. B. Leiba. IETF. May 2017. Best Current Practice. URL: https://www.rfc-editor.org/rfc/rfc8174
[TOUCH-EVENTS]
Touch Events. Doug Schepers; Sangwhan Moon; Matt Brubeck; Arthur Barstow. W3C. 10 October 2013. W3C Recommendation. URL: https://www.w3.org/TR/touch-events/
[UIEVENTS]
UI Events. Gary Kacmarcik; Travis Leithead. W3C. 7 September 2024. W3C Working Draft. URL: https://www.w3.org/TR/uievents/
[WEBIDL]
Web IDL Standard. Edgar Chen; Timothy Gu. WHATWG. Living Standard. URL: https://webidl.spec.whatwg.org/

D.2 参考情報の参照

[COMPAT]
Compatibility Standard. Mike Taylor. WHATWG. Living Standard. URL: https://compat.spec.whatwg.org/
[PointerEvents]
Pointer Events. Jacob Rossi; Matt Brubeck. W3C. 4 April 2019. W3C Recommendation. URL: https://www.w3.org/TR/pointerevents/
[PointerEvents2]
Pointer Events. Matt Brubeck; Rick Byers; Patrick Lauke; Navid Zolghadr. W3C. 4 April 2019. W3C Recommendation. URL: https://www.w3.org/TR/pointerevents2/
[WCAG22]
Web Content Accessibility Guidelines (WCAG) 2.2. Michael Cooper; Andrew Kirkpatrick; Alastair Campbell; Rachael Bradley Montgomery; Charles Adams. W3C. 12 December 2024. W3C Recommendation. URL: https://www.w3.org/TR/WCAG22/