JSでタッチデバイス判定する方法の最適解をChatGPTさんに聞いてみた。

現在使用中のデバイスがタッチデバイスかどうかを判定するコードとして、ざっくり下記のような手法がWEB上ではよく紹介されています。

  1. 'ontouchstart' in window でチェック
  2. navigator.maxTouchPoints > 0でチェック
  3. navigator.msMaxTouchPoints > 0でもチェック( 旧Edge・IE用? )
  4. matchMedia('(pointer:coarse)').matchesでチェック
  5. 'orientation' in windowでチェック

これらの組み合わせ方が色々なパターンで紹介されていて、結局どれが必要なの?というのがあやふやだったのでChatGPTさんに聞いてみました。

ChatGPTさんとのやりとり

※ ざっくり概要だけ再現します。

JSでタッチデバイスかどうかを判定するコードを教えて〜。(まずは普通にきいてみた)

自分

以下のコードでチェックできます。

if ('ontouchstart' in window || navigator.maxTouchPoints) {
  // タッチデバイスの場合の処理
}
  • ontouchstartプロパティは、タッチスクリーン上で指がタッチされたときに発生するイベント。
  • navigator.maxTouchPointsは、デバイスが同時にサポートするタッチポイントの数を返すプロパティで、これが1以上の場合、デバイスはタッチデバイスである可能性が高い。
GPT

ontouchstartでのチェックと、maxTouchPointsでのチェックは両方必要なの?

自分

はい。一部のデバイスやブラウザでは、maxTouchPointsが未定義または null である場合があります。そのため、ontouchstartも併用することで、より信頼性の高いチェックができます。

  • ontouchstartは多くのスマートフォンやタブレットなどのデバイスでサポートされているタッチデバイスによく使われます。
  • maxTouchPointsは、2-in-1コンピューターやタッチスクリーンを搭載したデスクトップコンピューターなど、タッチ機能を備えた異なる種類のデバイスで使用されます。

したがって、両方をチェックすることで、より幅広い範囲のタッチデバイスに対応することができます。

GPT

WEB上にはmatchMediaを使ったチェック方法も紹介されていますが、これは不要ですか?

自分

たしかに、matchMediaを使用してメディアクエリをチェックすることで、タッチデバイスかどうかを判定する方法もあります。

以下はそのコード例です。

if (matchMedia("(pointer: coarse)").matches) {
  // タッチデバイスの場合の処理
}

この方法は、CSSプロパティpointerを使用して、デバイスのポインティングデバイスの種類を判定します。pointer: coarseは、指やタッチペンなどの粗いポインティングデバイスを持つデバイスにマッチします。

ただし、この方法にはいくつかの欠点があります。一部のブラウザではmatchMediaがサポートされていない場合があるため、ブラウザの互換性に問題が生じる可能性があります。

したがって、ontouchstartmaxTouchPointsを併用した方法が、最も広くサポートされ、最も信頼性が高いと言えます。ただし、ブラウザのサポート状況や要件によっては、matchMediaを使用することも選択肢の一つとして考慮できます。

GPT

なるほど…!
追加で質問です。maxTouchPointsだけでなくmsMaxTouchPointsを併用する方法も見かけたのですが、これはモダンブラウザでは不要ですか?

自分

msMaxTouchPoints プロパティは、Microsoft Edge および Internet Explorer 11 でのみ使用されます。したがって、これらのブラウザ以外では、このチェックは不要です。現代的なブラウザでは、maxTouchPoints プロパティのみを使用すれば、タッチデバイスを検出することができます。したがって、モダンブラウザでこのチェックを行う必要はありません。

ただし、古いバージョンの Microsoft Edge がインストールされた Windows デバイスで動作する Web アプリケーションをサポートする場合は、msMaxTouchPoints プロパティを使用することが必要になるかもしれません。

また、Microsoft Edge の最新バージョンでは navigator.maxTouchPoints プロパティを使用することが推奨されており、msMaxTouchPoints プロパティは非推奨になっています。

GPT

では、モダンブラウザではmsMaxTouchPointsは不要ですよね?

自分

はい。現代的な Web アプリケーションでmsMaxTouchPoints プロパティを使用する必要はありません。ただし、過去のバージョンの Microsoft Edge をサポートする必要がある場合は、msMaxTouchPoints プロパティを使用する必要があります。

GPT

EdgeでmaxTouchPointsがサポートされたのはいつからですか?

自分

Microsoft Edge 17 以降でサポートされています。これは、2018年4月にリリースされたバージョンです。したがって、2018年4月以降にリリースされた Microsoft Edge バージョンでは、maxTouchPoints プロパティを使用することができます。

GPT

ありがとう。さらに追加で質問です。
'orientation' in windowでタッチデバイスかどうか判定する方法もあるようなのですが、これは現在でも有効ですか?

自分

"orientation"を使用してタッチデバイスかどうかを判定する方法は、かつては広く使われていましたが、現在では推奨されていません。このプロパティは、デバイスの方向(縦向きまたは横向き)を返すプロパティであり、タッチデバイスかどうかを判定するために使用することが意図されていないためです。

また、”orientation”プロパティは、一部のブラウザではサポートされていない場合があります。さらに、最新のモバイルデバイスでは、”orientation”プロパティが廃止され、代わりにwindow.screen.orientation.typeを使用することが推奨されています。

したがって、”orientation”プロパティを使用してタッチデバイスかどうかを判定することは、推奨されていません。代わりに、'ontouchstart' in windownavigator.maxTouchPointsmatchMedia("(pointer: coarse)").matchesを使用することをお勧めします。

GPT

結論

これらのやりとりをふまえ、msMaxTouchPointsは不要と判断し(orientationでの判定はもともと採用していない)、私は下記のコードを採用しました!

const IS_TOUCH_DEVICE =
    'ontouchstart' in window ||
    navigator.maxTouchPoints > 0 ||
    window.matchMedia('(pointer:coarse)').matches;