JavaScript
HTML5

PCとスマホの Pointer Events 挙動まとめ

Pointer Eventsとは

Pointerイベントは、マウス、タッチスクリーン、ペンなどのさまざまな入力を統合するべく策定されたDOMイベントです。

Version1は2015年にW3C勧告されています。
https://www.w3.org/TR/pointerevents1/

PC向けにMouseイベント、スマホ向けにTouchイベントというように、個別に実装しなくて良いなら助かりますね :grinning:

そして気になる各ブラウザの対応状況は・・・
https://caniuse.com/#feat=pointer

Safari系が未対応・・・っ!
iPhone・・・っ!! :innocent:

とりあえず現状どんな感じか、挙動を調べてみました。

各イベントの対応表

Pointer、Mouse、Touchの各イベントの対応はこんな感じでしょうか。

Pointer Events Mouse Events Touch Events
pointerdown mousedown touchstart
pointerup mouseup touchend
pointercancel - touchcancel
pointermove mousemove touchmove
pointerenter mouseenter -
pointerleave mouseleave -
pointerover mouseover -
pointerout mouseout -

実際に動かして挙動を調べる

全イベントを仕込んだテストページを用意しました。
各ブラウザで実際に動かして発火条件を調べます。
https://zprodev.github.io/interaction-event-test/#default

使用ブラウザ
Chrome 72.0.3626.28 beta
Chrome for Android 71.0.3578.99
Firefox 64.0.2
Safari 12.0.2
iOS Safari 12.0

(Windows系は追って・・・)

pointerdown

Chrome
Element上でマウスのボタンを押した時。

Chrome for Android
Element上でタッチを開始した時。

Firefox
Chromeと同じ。

Safari
非対応。

iOS Safari
非対応。

pointerup

Chrome
Element上でマウスのボタンを離した時。

Chrome for Android
pointerdown後、pointercancel発火前にElementから指を離した時。

Firefox
Chromeと同じ。

Safari
非対応。

iOS Safari
非対応。

pointercancel

Chrome
確認できず。

Android
pointerdown後、ある程度指をスライドした時。また、長押しにより文字列コピーなどのUIが表示された時。

Firefox
確認できず。

Safari
非対応。

iOS Safari
非対応。

pointermove

Chrome
Element上でマウスカーソルが移動した時。

Chrome for Android
pointerdown後、指のスライドでpointercancelが発生するまでの間。

Firefox
Chromeと同じ。

Safari
非対応。

iOS Safari
非対応。

pointerenter

Chrome
Element上にマウスカーソルが乗った時。

Chrome for Android
Element上でタッチを開始した時。

Firefox
Chromeと同じ。

Safari
非対応。

iOS Safari
非対応。

pointerleave

Chrome
Element外にマウスカーソルが移動した時。

Chrome for Android
pointerenter後、pointerupかpointercancelが発生した時。

Firefox
Chromeと同じ。

Safari
非対応。

iOS Safari
非対応。

pointerover

Chrome
Element上にマウスカーソルが乗った時と、子Element上にマウスカーソルが乗った時。

Chrome for Android
Element上でタッチを開始した時。

Firefox
Chromeと同じ。

Safari
非対応。

iOS Safari
非対応。

pointerout

Chrome
Element外にマウスカーソルが移動した時と、子Element外にマウスカーソルが移動した時。

Chrome for Android
pointerover後、pointerupかpointercancelが発生した時。

Firefox
Chromeと同じ。

Safari
非対応。

iOS Safari
非対応。

mousedown

Chrome
Element上でマウスのボタンを押した時。

Chrome for Android
Element上でタッチし、すぐに指を離した時。

Firefox
Chromeと同じ。

Safari
Chromeと同じ。

iOS Safari
Chrome for Androidと同じ。

mouseup

Chrome
Element上でマウスのボタンを離した時。

Chrome for Android
Element上でタッチし、すぐに指を離した時。

Firefox
Chromeと同じ。

Safari
Chromeと同じ。

iOS Safari
Chrome for Androidと同じ。

mousemove

Chrome
Element上でマウスカーソルが移動した時。

Chrome for Android
Element上でタッチし、すぐに指を離すか、長押しした時。

Firefox
Chromeと同じ。

Safari
Chromeと同じ。

iOS Safari
Element上でタッチし、すぐに指を離した時。

mouseenter

Chrome
Element上にマウスカーソルが乗った時。

Chrome for Android
Element上でタッチし、すぐに指を離すか、長押しした時。
発火後は、mouseleaveが発火するまで再発火しない。

Firefox
Chromeと同じ。

Safari
Chromeと同じ。

iOS Safari
Element上でタッチし、すぐに指を離した時。
発火後は、mouseleaveが発火するまで再発火しない?(mouseleaveが確認できなかったため不明)

mouseleave

Chrome
Element外にマウスカーソルが移動した時。

Chrome for Android
mouseenter後、Element外をタッチし、すぐに指を離すか、長押しした時。

Firefox
Chromeと同じ。

Safari
Chromeと同じ。

iOS Safari
確認できず。

mouseover

Chrome
Element上にマウスカーソルが乗った時と、子Element上にマウスカーソルが乗った時。

Chrome for Android
Element上か子Element上でタッチし、すぐに指を離すか、長押しした時。
同じElement上では連続で発火しない。

Firefox
Chromeと同じ。

Safari
Chromeと同じ。

iOS Safari
Element上か子Element上でタッチし、すぐに指を離した時。
同じElement上では連続で発火しない。

mouseout

Chrome
Element外にマウスカーソルが移動した時と、子Element外にマウスカーソルが移動した時。

Chrome for Android
mouseover後、別のElementをタッチし、すぐに指を離すか、長押しした時。

Firefox
Chromeと同じ。

Safari
Chromeと同じ。

iOS Safari
mouseover後、別のElementをタッチし、すぐに指を離した時。

touchstart

Chrome
非対応。

Chrome for Android
Element上でタッチを開始した時。

Firefox
非対応。

Safari
非対応。

iOS Safari
Chrome for Androidと同じ。

touchend

Chrome
非対応。

Chrome for Android
touchstart後、画面から指を離した時。

Firefox
非対応。

Safari
非対応。

iOS Safari
Chrome for Androidと同じ。

touchcancel

Chrome
非対応。

Chrome for Android
確認できず。

Firefox
非対応。

Safari
非対応。

iOS Safari
確認できず。

touchmove

Chrome
非対応。

Chrome for Android
touchstart後、指をスライドしている間。

Firefox
非対応。

Safari
非対応。

iOS Safari
Chrome for Androidと同じ。

まとめ

PC系ブラウザのPointerとMouseは挙動が同じなので、MouseからPointerに置き換えても問題なさそうですね。(非対応のSafari以外)
AndroidのTouchとPointerは使用感が異なるので、迂闊に置き換えるのは危なそうです。

Safari未対応の件もあり、インタラクションイベントのコード共通化はもう少し先になりそうです :pensive: