今後の方向性を示す

Sérgio Gomes

かつては、ウェブ上のものを指すことは簡単でした。マウスを動かして ボタンを押すだけ。それまではなかった マウスは 1 つのマウスとしてエミュレートされ、開発者は何を頼りにすればよいかを正確に把握していました。

シンプルだからといって、必ずしも良いとは限りません。時間が経つにつれて すべてがマウスだった(あるいはそのふりをしている)わけではないことも重要です。 感圧センサーとチルト対応ペンで自由自在に創造できます。 指を使うため、必要なものはデバイスと手だけでした。なぜなら 指を 2 本以上入れないといけませんか?

タッチイベントがあった それは完全に独立した API であり、 2 種類のイベントモデルをコーディングする必要が マウスとタップの両方をサポートしますChrome 55 では新しい標準が標準装備 両方のモデルを統合する、ポインタ イベントです。

単一のイベントモデル

ポインタ イベントは、 タップ、ペン、マウスを組み合わせたブラウザのポインタ入力モデル 1 つのイベントセットにすることができます例:

document.addEventListener('pointermove',
    ev => console.log('The pointer moved.'));
foo.addEventListener('pointerover',
    ev => console.log('The pointer is now over foo.'));

こちらは利用可能なすべてのイベントのリストです。 マウスイベントに精通しているとしましょう。

pointerover ポインタが要素の境界ボックスに入った。 これは、カーソルを合わせるデバイスの場合は直ちに、または pointerdown イベントを返します。
pointerenter pointerover に似ていますが、バブルとハンドルは表示しません。 異なる子孫を指定します。 仕様の詳細
pointerdown ポインタがアクティブなボタン状態になり、いずれかのボタンが 押されたか連絡先が確立されたことを通知します。これは、 できます。
pointermove ポインタの位置が変わりました。
pointerup ポインタがアクティブなボタンの状態から離れました。
pointercancel エラーが発生しました。ポインタが何も出力しない可能性があります 表示されます。つまり、進行中のアクションをすべてキャンセルして、 入力状態に戻すことができます。
pointerout ポインタが要素または画面の境界ボックスから離れた状態。また、 pointerup(デバイスがホバーをサポートしていない場合)
pointerleave pointerout に似ていますが、バブルとハンドルは表示されません。 異なる子孫を指定します。 仕様の詳細
gotpointercapture 要素がポインタのキャプチャを受信した。
lostpointercapture キャプチャ中のポインタが リリースされます。

さまざまな入力タイプ

一般的にポインタ イベントを使用すると、入力に依存しない形でコードを記述できます。 入力デバイスごとに個別のイベント ハンドラを登録する必要がありません。 もちろん、入力タイプの違いには留意する必要があります。たとえば、 マウスオーバーという概念が適用されますさまざまな入力デバイスタイプを区別したい場合、たとえば 入力ごとに個別のコード/機能を使用できます。ただし、 pointerType プロパティを使用して、同じイベント ハンドラ内で PointerEvent 行うことができます。たとえば、サイド ナビゲーション ドロワーをコーディングする場合、 pointermove イベントに次のロジックを実装しているとします。

switch(ev.pointerType) {
    case 'mouse':
    // Do nothing.
    break;
    case 'touch':
    // Allow drag gesture.
    break;
    case 'pen':
    // Also allow drag gesture.
    break;
    default:
    // Getting an empty string means the browser doesn't know
    // what device type it is. Let's assume mouse and do nothing.
    break;
}

デフォルトのアクション

タップ対応ブラウザでは、特定の操作でページのスクロール、ズーム、更新が行われます。 タッチイベントの場合は、これらのデフォルトのイベントに加えてイベントも受け取りますが、 たとえば、ユーザーがスクロールしている間も touchmove が呼び出されます。

ポインタ イベントでは、スクロールやズームなどのデフォルトのアクションがトリガーされると、 pointercancel イベントが発生し、ブラウザが 作成します。例:

document.addEventListener('pointercancel',
    ev => console.log('Go home, the browser is in charge now.'));

組み込みの速度: このモデルを使用するとデフォルトでパフォーマンスが向上しますが、 タッチイベントと比較すると、 パッシブ イベント リスナー 同じレベルの応答性が実現されます。

ブラウザによる制御を停止するには、 touch-action CSS プロパティ。要素で none に設定すると、すべてが無効になります その要素に対して開始されたブラウザ定義のアクション他にも きめ細かい制御に使用するその他の値(pan-x など)は、 X 軸の動きには反応するが Y 軸の動きには反応しない。Chrome 55 次の値をサポートしています。

auto デフォルト:ブラウザはデフォルトのアクションを実行できます。
none ブラウザにはデフォルトのアクションの実行が許可されていません。
pan-x ブラウザで行えるのは水平スクロールのデフォルトのアクションのみです。
pan-y ブラウザで可能なのは垂直スクロールのデフォルトのアクションのみです。
pan-left ブラウザで実行できる水平スクロールのデフォルトのアクションは、 ページを左にパンします
pan-right ブラウザで実行できる水平スクロールのデフォルトのアクションは、 ページを右にパンします
pan-up ブラウザで垂直スクロールのデフォルトのアクションしか実行できない。 ページを上にパンするだけです
pan-down ブラウザで垂直スクロールのデフォルトのアクションしか実行できない。 ページを下にスクロールします
manipulation ブラウザで行える操作はスクロールとズームのみです。

ポインタ キャプチャ

壊れた mouseup のデバッグにストレスを感じたことがありますか? ユーザーがボタンを離したことが原因であることが判明するまで クリック目標の範囲外ですか?思いませんか?わかった、私だけかもしれない。

とはいえ、これまではこの問題に対して有効な方法がありませんでした。承知しました。 ドキュメントに mouseup ハンドラを設定し、状態を 追跡できるようにすることですこれは最もクリーンなソリューションではありません。 ただし、特にウェブ コンポーネントを作成して、すべてを適切に保ち、 できます。

ポインタ イベントを使用すると、はるかに優れた解決策が得られます。つまり、ポインタをキャプチャし、 これにより、pointerup イベント(または検出できないイベント)を確実に取得できます。 できます。

const foo = document.querySelector('#foo');
foo.addEventListener('pointerdown', ev => {
    console.log('Button down, capturing!');
    // Every pointer has an ID, which you can read from the event.
    foo.setPointerCapture(ev.pointerId);
});

foo.addEventListener('pointerup', 
    ev => console.log('Button up. Every time!'));

ブラウザ サポート

現時点では、ポインタ イベントは Internet Explorer 11 でサポートされていますが、 Microsoft Edge、Chrome、Opera で、Firefox では一部サポートされています。Google Chat では 最新リストについては caniuse.com をご覧ください。

ポインタ イベント ポリフィルを使用して、 ギャップを埋めることができますまたは、実行時にブラウザのサポートを確認することで、 明白:

if (window.PointerEvent) {
    // Yay, we can use pointer events!
} else {
    // Back to mouse and touch events, I guess.
}

ポインタ イベントは、漸進的なエンハンスメントに適した 初期化メソッドを変更して上記のチェックを実行し、ポインタ イベントを追加します。 if ブロック内で作成し、マウス/タッチ イベント ハンドラを else ブロック。

ぜひお試しになって、ご意見、ご感想をお寄せください。