JavaScriptでiOS端末を判別する際、次のように「iPhone」「iPad」「iPod」のいずれかの文字列が含まれているかどうかを判断することが多いのではないでしょうか。
const ua = navigator.userAgent
const isIOS = ua.indexOf("iPhone") >= 0
|| ua.indexOf("iPad") >= 0
|| navigator.userAgent.indexOf("iPod") >= 0
正規表現 (RegExp.prototype.test() - JavaScript | MDN) を使うと、次のように短くできます。
const isIOS = /iP(hone|(o|a)d)/.test(navigator.userAgent)
/iP(hone|(o|a)d)/
が「iPhone、iPod、iPad」を表現します。test(対象の文字列)
を使うことで、対象の文字列に「iPhone、iPod、iPad」が含まれているかどうかを判定できます。判定部分だけで見ると43文字のコードで充分短いように見えますが、もっと短くすることはできないのでしょうか。
/[ \(]iP/
でiOS端末は判定できる
ユーザーエージェントの一覧が記載されている「歌うキツネ : User-Agent (ユーザー エージェント) 一覧」(※1)を見ると、iPhone、iPodは「(半角スペース)iP
」が含まれているか、iPadは「(iP
」が含まれているかどうか(※2)で判定できることがわかります。したがって、iOS端末のユーザーエージェント判別は、次のようなコードで実現可能となります。
const isIOS = /[ \(]iP/.test(navigator.userAgent)
[ \(]
: 半角スペースまたは(
が含まれる
iP
: iP
が含まれる
組み合わせることで、「半角スペース、または(
から始まり、iP
が続く文字列」という意味です。
判定部分だけで見ると35文字のコード。多分これが一番短いコードだと思います。ちなみにIE 11でもエラーになることなく動作するコードです。
※1 ページに記載されているのは2016年12月までの情報
※2 半角スペースなしの/iP/
だけだと、Huawei系の端末もヒットする。
最後に
実際の案件で使うと可読性が著しく下がる上、(半角スペース)iPomeranian
のようなユーザーエージェントを持つ端末が将来登場する可能性も0ではありません。
よって、/[ \(]iP/.test(navigator.userAgent)
は使わず、/iP(hone|(o|a)d)/.test(navigator.userAgent)
くらいを使うのがよいでしょう(※)。
もし/[ \(]iP/.test(navigator.userAgent)
よりも短いコードがあれば、お知らせください。
※ 同様の理由で iPhone Chrome Safari Edge Fox Android
のようなユーザーエージェントを持つブラウザが登場する可能性もあるので、「iPhone
が含まれるかどうか」も完璧な判定式だとは思いませんが。。。
事例 → 「Microsoft Edgeのユーザーエージェントがカオスなので注意」