ユーザーがページ内の特定の領域をドラッグ操作するなにかを実装するときの話。
それを実装してて誰しもがハマるのが、ユーザーがその領域を触ってるときにページ全体がスクロールされちゃったりするというもの。
で、これを防ぐための方法について。
ev.preventDefault()
古から伝わる方法で、今までずっとこうしてた。
`touchstart`とか`touchmove`とか、ユーザーが画面に触れている間、`preventDefault()`でキャンセルする。
たしかにコレで目的は達成できるけど、いくつかの面で不都合がある。
- パフォーマンスが悪い
- できれば`passive: true`にしたいくらいなのに
- そのコンテナの配下の要素で、`click`イベントが使えない
- `touchstart`などでイベントをキャンセルすると、後続のイベントがキャンセルされる仕様らしい
- https://developer.mozilla.org/en-US/docs/Web/API/Touch_events/Supporting_both_TouchEvent_and_MouseEvent#event_order
そういうわけなので、この用途において`preventDefault()`はもはや適切な解決策ではないということ。
CSS: touch-action
そこで使うのが、CSSの`touch-action`プロパティ。
たとえば`touch-action: none`と指定すると、端的にいうとその要素をタッチ端末で触れなくなる。
(正確にはこの挙動は許可する、これは許可しないのように選べる)
なのでJavaScriptで制御して、ドラッグやらピンチインやら操作したい要素には、決まってこのプロパティを指定すべし。
ということを、流行りのジェスチャー系のライブラリのコードを読んでて知ったのでした。
余談
5年前に自分がハマってて、何に使うんかわからんって言ってた。
今ならわかる・・このために使うんやと・・。嗚呼。