JavaScript ユーザエージェント条件分岐便利スニペット

下記に記載の内容では、2015年現在新たに登場してきているOSまで対象にするには限界がありますので、Mobileの判定をMobileとTabletにだけフィーチャーさせた2015年版JavaScriptユーザエージェント判別もあわせてご参照ください。

jQuery.supportだけで代表的なブラウザの判別を行うことができなくなってしまったので、UA情報には依存しないブラウザがサポートしている機能でブラウザ判別を行う試みです。ただし、モバイルかどうかの判別をするためにWindows Phoneに限ってはUA情報に依存する必要があります。

判別用コード

var _ua = (function(){
 return {
  ltIE6:typeof window.addEventListener == "undefined" && typeof document.documentElement.style.maxHeight == "undefined",
  ltIE7:typeof window.addEventListener == "undefined" && typeof document.querySelectorAll == "undefined",
  ltIE8:typeof window.addEventListener == "undefined" && typeof document.getElementsByClassName == "undefined",
  ltIE9:document.uniqueID && typeof window.matchMedia == "undefined",
  gtIE10:document.uniqueID && window.matchMedia,
  Trident:document.uniqueID,
  Gecko:'MozAppearance' in document.documentElement.style,
  Presto:window.opera,
  Blink:window.chrome,
  Webkit:typeof window.chrome == "undefined" && 'WebkitAppearance' in document.documentElement.style,
  Touch:typeof document.ontouchstart != "undefined",
  Mobile:(typeof window.orientation != "undefined") || (navigator.userAgent.indexOf("Windows Phone") != -1),
  ltAd4_4:typeof window.orientation != "undefined" && typeof(EventSource) == "undefined",
  Pointer:window.navigator.pointerEnabled,
  MSPoniter:window.navigator.msPointerEnabled
 }
})();

解説

条件分岐のコード自体で、何のために条件分岐しているのかが一目瞭然になってると便利というわけで作ったスニペットです。

  • ltIE6は、addEventListenerに対応しておらず、且つmaxHeightに対応していないという条件でIE6以下を導き出しています。
  • ltIE7は、addEventListenerに対応しておらず、且つIE8から対応のquerySelectorAllに対応していないという条件でIE7以下を導き出しています。
  • ltIE8は、addEventListenerに対応しておらず、且つIE9から対応のgetElementsByClassNameに対応していないという条件でIE8以下を導き出しています。
  • IE9以下は、IEオリジナルのオブジェクトであるdocument.uniqueIDオブジェクトをもっていることと、IE10から対応しているwindow.matchMediaオブジェクトをもっていないことで導き出しています。またIE◯◯以上だけを条件にしたいのであればdocument.documentModeオブジェクトでバージョンが出力されるので、document.documentMode === 10であればIE10のみ、document.documentMode >= 11であればIE11以上を対象にすることができます。
  • window.operaは旧Presto版Operaしかもっていないオリジナルのオブジェクトで、MozAppearanceはFirefoxしかもっていないオリジナルのdocumentElement.styleプロパティで、window.choromeはChromium限定のChromeとBlink版Operaしかもっていないオリジナルのオブジェクトでそれぞれを導き出しています。
  • Webkitは、WebkitAppearance単独ではChromeもBlink版Operaももっているので、Chromium限定のwindow.chromeはもっていないことを条件で導き出しています。
  • Mobileは、window.orientationがundefined以外の何かしらの値をもっているということは傾きを判定できるスマートフォンやタブレット(iOS4以上、Android2.3以上、BlackBerry)のモバイル端末であると導き出しています。ただし、Windows Phoneに限ってはwindow.orientationをundefinedで返すため、UA情報にWindows Phoneの文字列があるかどうかでモバイル端末であると導き出しています。
  • ltAd4_4は、Android4.4以上とそれ以前とでは機能面が大きく違うため、window.orientationがundefined以外の何かしらの値をもっていることとあわせて、iOS4以上が実装しているEventSource APIをAndroidはAndroid4.4からサポートしたため、これをサポートしていないことを条件にAndroidのみのAndroid4.3以下であることを導き出してます。
  • タッチ周りはそれぞれイベントに対応しているかどうかで導き出しています。

たとえば、IE9とかFirefoxとかChromeとかOperaとかSafariとかのモダンブラウザのみに適用するコードであれば

if(!_ua.ltIE8){
 //この中のコードはモダンブラウザ用
}

IE8以下のみに適用するコードであれば、

if(_ua.ltIE8){
 //この中のコードはIE8以下用
}

IE7以下のみに適用するコードであれば、

if(_ua.ltIE7){
 //この中のコードはIE7以下用
}

IE6以下のみに適用するコードであれば、

if(_ua.ltIE6){
 //この中のコードはIE6以下用
}

IE限定でIE9以上のみに適用するコードであれば、

if(_ua.Trident && !_ua.ltIE8){
//この中のコードはIE限定でIE9以上用
}

IE限定でIE10以上のみに適用するコードであれば、

if(_ua.Trident && !_ua.ltIE9){
//この中のコードはIE限定でIE10以上用
}
//次の場合も同じです
if(_ua.gtIE10){
//同上
}

デスクトップとモバイル含めてFirefox限定で適用するコードであれば、

if(_ua.Gecko){
 //この中のコードはデスクトップ、モバイル両方のFirefox用
}

デスクトップとモバイル含めてSafari限定で適用するコードであれば、

if(_ua.Webkit){
 //この中のコードはデスクトップ、モバイル両方のSafari用
}

デスクトップとモバイル含めてChromeとOpera限定で適用するコードであれば、

if(_ua.Blink){
 //この中のコードはデスクトップ、モバイル両方のChromeとOpera用
}

旧Presto版OperaとOpera Mini限定で適用するコードであれば、

if(_ua.Presto){
 //この中のコードは旧Presto版OperaとOpera Mini用
}

スマートフォンとかタブレットのモバイル端末のみに適用するコードであれば、

if(_ua.Mobile){
 //この中のコードはスマートフォンとかタブレットなどのモバイル端末用
}

デスクトップ版Firefoxとモバイル版Firefoxとで適用コードを振り分ける場合でれば、

if(_ua.Gecko && !_ua.Mobile){
 //この中のコードはデスクトップ版Firefoxのみに適用
}else if(_ua.Gecko && _ua.Mobile){
 //この中のコードはモバイル版Firefoxのみに適用
}

デスクトップ版Safariとモバイル版Safari(iOS, Android)とで適用コードを振り分ける場合でれば、

if(_ua.Webkit && !_ua.Mobile){
 //この中のコードはデスクトップ版Safariのみに適用
}else if(_ua.Webkit && _ua.Mobile){
 //この中のコードはモバイル版Safariのみに適用
//Android BrowserやAndroid版OperaはWebkitを採用しているので、モバイル版Safariとみなします
}

デスクトップ版Chrome&Operaとモバイル版Chrome(Android用)とで適用コードを振り分ける場合でれば、

if(_ua.Blink && !_ua.Mobile){
 //この中のコードはデスクトップ版ChromeとOperaのみに適用
}else if(_ua.Blink && _ua.Mobile){
 //この中のコードはモバイル版Chrome for Androidのみに適用
 //iOS版Chromeはwindow.chromeが存在しないためモバイル版Safari扱いとなる
}

ゆえに、これまでのAndroid標準ブラウザとChrome for Androidで適用するコードをわけるのであれば、

if(_ua.Blink && _ua.Mobile){
 //この中のコードはモバイル版Chrome for Androidのみに適用
}else if(_ua.Webkit && _ua.Mobile){
 //この中のコードはWebkitベースのモバイルブラウザ用
}

スマートフォンとかタブレットのタッチデバイスに適用するコードであれば、

if(_ua.Touch){
 //この中のコードはタッチデバイス対応端末用
}

癖の多いAndroidもAndroid4.4(kitkat)未満に適用するコードであれば、

if(_ua.ltAd4_4){
 //この中のコードはAndroid 4.4(kitkat)未満のAndroidのみに適用
}

マウス、タッチ、ペンデバイスのタッチ周り全般に対応するUAに適用するコードであれば、

if(_ua.Pointer){
 //この中のコードはマウス、タッチ、ペンデバイス対応UA用(現在はIE11のみ)
}

ちなみにIE10にも適用するはベンダー識別子が必要なので(IE11から不要)、

if(_ua.MSPointer){
 //この中のコードはデスクトップのマウス、タッチ、ペンデバイス対応IE10用
}

という具合に使います。

上で紹介しているスニペットは、用途にあわせて増やしたり減らしてたりしてもらうと、さらに便利になるんじゃないでしょうか。とくに複数人での開発とかには。

サンプル

Updated / Published