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:

> 2019/6/10 追記
> iOS13（Safari13）で対応されます :tada:


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

## 各イベントの対応表

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

|[Pointer Events](https://www.w3.org/TR/pointerevents1/)|[Mouse Events](https://www.w3.org/TR/uievents/#events-mouseevents)|[Touch Events](https://www.w3.org/TR/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: