JavaScriptでブラウザを判定して処理を条件分岐する方法

javascript

ブラウザの違いによってJavaScriptの挙動が違って動かない」、または、「特定のブラウザのみに対応するJavaScriptを設置したい」、「『お使いのブラウザはEdgeです、このサイトを快適にご覧おただくにはChromeの使用を推奨いたします。』というように、ブラウザを判別して誘導文章を表示したい。」といったことはないでしょうか?
今回はこういた問題に対応するためにユーザーエージェントを使ってブラウザ判定をし、その結果によって処理するJavaScriptを別ける方法をご紹介します。

ブラウザを判定するユーザーエージェントについて

JavaScriptを使ってブラウザーを判定する場合「userAgent」を利用します。このユーザーエージェントプロパティを使って取得したブラウザ情報から現在閲覧しているブラウザは何であるかを判別するのです。
ユーザーエージェントを取得するための記述は以下になります。

これで、ブラウザの情報を取得できたのですが、ユーザーエージェントを使って取得できる情報は大文字・小文字が乱立してみにくい文字列なので、全て大文字、または全て小文字の統一してあげるほうが見やすくなります。そこで先ほどのソースに「toLowerCase()」を加えてこの文字列を扱いやすいように修正します。

これで、ユーザーエージェントとから取得したブラウザ情報が記載された文字列は見やすくなりました。この取得した情報からアクセスされたブラウザーに関する情報を見つけ出し条件式を作ることでブラウザ判定が可能になります。

ブラウザーの違いを識別する方法

先ほどのwindow.navigator.userAgent;を使うと下記のような文字列を取得することができます。

上記は、今閲覧頂いているブラウザのユーザーエージェントを表示させたものですが、こういった文字列からそのブラウザにしかない識別に使えるワードをピックアップして条件式をつくっていくのです。

各ブラウザーを識別するために使える識別子をまとめたものが下記になります。
先ほどのユーザーエージェントで取得した文字列の中にこの「識別子」が含まれているか含まれていないかでどのブラウザーに該当するかを判定します。

ブラウザ ユーザーエージェントの識別子
IE(11未満) MSIE
IE(11以上) Trident
旧Edge Edge
Chrome Chrome
Safari Safari
FireFox FireFox

この表は代表的なブラウザーの情報を記載しております。2020年8月現在の情報であり、今後もブラウザーのバージョンアップなどで変わる可能性があります。

IEに関しては、IE10までと、IE11とで識別子が違うので注意が必要です。
また、Edgeに関しては、2020年1月以前までは、「Edge」でしたが新しいEdgeからはChromium版になったので新Edgeは「Chrome」と同等と考えていいかと思います。(もしどうしても特定する必要がある場合は「Edg」という識別子で判別可能です。)

ちなみにOperaの現行バージョンもChromium版で配布されておりこちらも「Chrome」と同等の扱いで問題ないです。(もしOperaであることを特定する必要がある場合は「OPR」という識別子で判別可能です。)

ブラウザーの違いを判別して分岐する方法

上記はInternet Explorerを判別する場合のサンプルになります。
このサンプルはIE10以前とE11に対応させるために演算子or(||)を使用しています。「MSIE」、「Trident」の識別子は取得したユーザーエージェントを「toLowerCase()」ですべて小文字に変換しているので、小文字で比較します。判定には、「indexOf()」を利用しています。値が見つからない場合は -1が返ってくるので、その値の有無をIF文で条件分岐しています。
通常はこの方法でブラウザを判定できるのですが、特殊なケースも存在します。
そこで重要になってくるのは比較する順番です。

ブラウザ判定する順について

下記は、比較するべき順に並べたサンプルです。

なぜ、比較する順が大切なのかと言うと。
「Google Chrome」のユーザーエージェントの文字列の中には「Chrome」という文字列と「Safari」という文字列が含まれている。
「旧Edge」のユーザーエージェントの文字列の中には「Edge」はもちろん「Chrome」という文字列と「Safari」という文字列が含まれているといった特殊なケースがあるからです。
このため、「Safari」を判定する前に「Edge」と「Chrome」を先に判定しておかなければならない。また「Chrome」を判定する場合は先に「Edge」を判定しておかなければならないということになるのです。

上記のことを踏まえて、もしSafariのみに対応させたい場合は下記のように記述する必要があります。

旧Edgeに関しては、自動更新で新Edgeに置き換りつつあるので、今後対応する必要がないかもしれません。旧Edgeを除外する場合は「userAgent.indexOf(‘edge’) != -1 ||」の部分はいりません。

必要に応じて使い分ができるようになっておくと便利だと思います。是非ご活用ください。