jQuery.supportでのブラウザ判別

Updated / Published

下記に記載の内容は情報が古くなったために正しく動作しなくなりました。JSでのUA条件分岐便利スニペットとして、代替案を提示しています。

jQueryでブラウザを判別するjQuery.browserのAPIは1.3より非推奨のため、代わりにブラウザがサポートする機能を判別するAPIであるjQuery.supportで代表的なブラウザの判別方法をまとめてみました。これならUser Agentが偽装されても大丈夫、UA情報には依存しないサポートしている機能だけでのブラウザ判別を行う試みです。

jQuery.browserは非推奨

if(jQuery.browser.msie){
alert('あなたがお使いのブラウザはIEです');
}else if(jQuery.browser.mozilla){
alert('あなたがお使いのブラウザはFirefoxです');
}else if(jQuery.browser.webkit){
alert('あなたがお使いのブラウザはchromeもしくはsafariです');
}else if(jQuery.browser.opera){
alert('あなたがお使いのブラウザはoperaです');
}

jQuery.browserを使えば、上記の簡単なコードだけでブラウザを判別した条件分岐が行えます。加えてバージョンの判別もjQuery.browser.versionを使ってできます。

if(jQuery.browser.msie && parseInt(jQuery.browser.version) == 8){
alert('あなたがお使いのブラウザはIE8です');
}else if(jQuery.browser.msie && parseInt(jQuery.browser.version) == 7){
alert('あなたがお使いのブラウザはIE7です');
}else if(jQuery.browser.msie && parseInt(jQuery.browser.version) == 6){
alert('あなたがお使いのブラウザはIE6です');
}

jQuery.browserjQuery.browser.versionはすごく便利ですが、jQuery1.3からはどちらも非推奨となっています。1.3以降のバージョンでは後方互換とプラグイン利用のためにまだ含まれていますが、今後のjQueryのバージョンアップに伴い、この機能は廃止される見通しです。また、飽くまでもこれらはnavigator.userAgentの値をもとにしており、UA情報は簡単に偽装することもできます。そこで、代わりにブラウザがサポートする機能に基づいて判別を行うjQuery.supportを使うことが推奨されています。

jQuery.supportについて

jQuery.supportは、ブラウザごとの各機能のサポート状態をBoolean型の true or falseの値で返すAPIです。各機能にあたるプロパティには次のようなものがあります。

leadingWhitespace
innerHTMLで、先頭に空白があった場合にそれを残して返すブラウザであればtrueです。
tbody
table要素内に、tbody要素が無い状態を許可する(省略時に自動的に付加しない)ブラウザであればtrueです。
htmlSerialize
innerHTMLを用いた際に、シリアライズされた値を返すブラウザであればtrueです。
style
getAttribute("style")で要素に記述されたstyle属性値を取得できるブラウザであればtrueです。
hrefNormalized
href属性の値を取得する際に、属性値をそのまま返す(勝手に補完しない)ブラウザであればtrueです。
opacity
opacityによる透明度を指定する機能を実装しているブラウザであればtrueです。
cssFloat
floatの値を取得する場合にstyle.cssFloatで取得できるブラウザであればtrueです。
checkOn
チェックボックスの値が指定されていない場合のデフォルト値が"on"であるブラウザであればtrueです(webkitはデフォルト値が""の空なので、falseです)。
deleteExpando
拡張した要素の属性を、delete演算子で削除できるブラウザであればtrueです。
checkClone
cloneNode()を使用して要素を複製する場合に要素のチェック状態も含めコピーできるブラウザでればtrueです。
scriptEval
appendChild()createTextNode()で要素を追加した際、そこにスクリプトが含まれていると、それを自動的に実行できるブラウザであればtrueです。
noCloneEvent
要素がコピーされる場合に、元の要素がもっていたイベントハンドラをコピーしないブラウザであればtrueです。
boxModel
W3C CSS Box Model に基づいてページをレンダリングしているブラウザであればtrueです。

これらのプロパティのブラウザ毎の値を一覧表にまとめると、次の通りです。

プロパティ名Chrome
5+
Safari
5+
Firefox
3.6+
Opera
10.5+
IE6IE7IE8IE9
leadingWhitespacetruetruetruetruefalsefalsefalsetrue
tbodytruetruetruetruefalsefalsetruetrue
htmlSerializetruetruetruetruefalsefalsefalsetrue
styletruetruetruetruefalsefalsetruetrue
hrefNormalizedtruetruetruetruefalsefalsetruetrue
opacitytruetruetruetruefalsefalsefalsetrue
cssFloattruetruetruetruefalsefalsefalsetrue
checkOnfalsefalsetruetruetruetruetruetrue
deleteExpandotruetruetruetruefalsefalsefalsetrue
checkClonetruetruetruetruetruetruetruetrue
scriptEvaltruetruetruetruefalsefalsefalsetrue
noCloneEventtruetruetruetruefalsefalsefalsefalse
boxModeltruetruetruetruetruetruetruetrue
submitBubblestruetruetruetruefalsefalsefalsetrue
changeBubblestruetruetruetruefalsefalsefalsetrue

chromeとsafariを対象とする場合

if(!jQuery.support.checkOn){
alert('あなたがお使いのブラウザはChromeもしくはSafariっぽいです');
}

if文の条件式の中で!をつけたので、checkOnfalseであればこの条件文に該当します。該当するのはwebkitだけなので、これでchormeとsafariのみに振り分けたコードを記述できます。なお、Android標準ブラウザ、iPhone / iPad標準ブラウザといったスマートフォンも同じChromeとSafariなので、この条件に合致します。

FirefoxとOperaを対象とする場合

if(jQuery.support.checkOn && jQuery.support.noCloneEvent){
alert('あなたがお使いのブラウザはFirefoxもしくはOperaっぽいです');
}

まず、checkOntrue条件なので、chromeとsafariがこれにはじかれ、IEの全バージョンでfalseが返るnoCloneEventをand条件に加えることで、FirefoxかOperaのみに振り分けたコードを記述できます。さらにここから、FirefoxかOperaかを判別するには、jQueryではなく、window.globalStorageを使います。globalStorageを使うのはFirefoxのみです。ただし、問題があります。globalStorageがWeb Storageの仕様自体から削除されたため、今後FirefoxのアップデートによってglobalStorage自体が削除されると、以下のOperaとFirefoxの判別は今後通用しなくなるかもしれませんということで注意してください。一応、Firefox4 betaではglobalStorage自体は残されていたので問題なく動作確認できています。

if(jQuery.support.checkOn && jQuery.support.noCloneEvent && window.globalStorage){
alert('あなたがお使いのブラウザはFirefoxっぽいです');
}else if(jQuery.support.checkOn && jQuery.support.noCloneEvent && !window.globalStorage){
alert('あなたがお使いのブラウザはOperaっぽいです');
}

IEのみを対象として各バージョンでの振り分けもできるようにしたい場合

ブラウザ判別でのコード分岐は特にIEにおいて活躍することが多いので、いろいろなアプローチを取り上げてみます。

IE9を除く、IE6,7,8を対象にしたい場合

if(!jQuery.support.opacity){
alert('あなたがお使いのブラウザはIE6,7,8っぽいのいずれかです');
}

IE9からはopacityをサポートしているので、これをサポートしていない(falseが返る)のはIE6,7,8だけです。IE6,7,8に対してのみまとめて書きたい場合に使えます。特にIE9は他のモダンブラウザと並ぶくらいサポートが良化してきているので、IE9を除くIE6,7,8にだけという場面は今後も頻発するかと思います。

IE6,7,8の各バージョン判別もできるようにしたい場合

if(!jQuery.support.opacity){
    if(!jQuery.support.style){
    alert('あなたがお使いのブラウザはIE6,7っぽいのどちらかです');
    }else{
    alert('あなたがお使いのブラウザはIE8っぽいです');
    }
}

styleはIE8からサポートしているのでIE6,7とIE8を切り分けることができます。しかし、IE6とIE7の切り分けがまだできていません。IE6とIE7をブラウザのサポート状態だけで切り分けるには、こちらもjQueryではなくtypeof document.documentElement.style.maxHeight != "undefined"を利用します。これはmaxHeightプロパティをサポートしているかどうかで判別します。なお、IE8の互換表示モード時はIE7の部分が通ります。

if(!jQuery.support.opacity){
    if(!jQuery.support.style){
        if (typeof document.documentElement.style.maxHeight != "undefined") {
        alert('あなたがお使いのブラウザはIE7っぽいです');
        }
        else {
        alert('あなたがお使いのブラウザはIE6っぽいです');
        }
    }else{
    alert('あなたがお使いのブラウザはIE8っぽいです');
    }
}

IE9のみを対象にしたい場合

if(!jQuery.support.noCloneEvent && jQuery.support.opacity){
alert('あなたがお使いのブラウザはIE9っぽいです');
}

noCloneEventfalseなのはIEだけなので、まずIEのみに対象を絞り込むことができ、IE6,7,8,9の中でopacitytrueなのはIE9だけなので、IE6,7,8を除いたIE9のみの条件分岐が可能です。

自分のブラウザを判別してみよう!

if(!jQuery.support.checkOn && jQuery.support.checkClone){
document.write('あなたがお使いのブラウザはchromeもしくはsafariっぽいです');
}else if(jQuery.support.checkOn && jQuery.support.noCloneEvent && window.globalStorage){
document.write('あなたがお使いのブラウザはFirefoxっぽいです');
}else if(jQuery.support.checkOn && jQuery.support.noCloneEvente && !window.globalStorage){
document.write('あなたがお使いのブラウザはOperaっぽいです');
}else if(!jQuery.support.noCloneEvent && jQuery.support.opacity){
document.write('あなたがお使いのブラウザはIE9っぽいです');
}else if(!jQuery.support.opacity){
    if(!jQuery.support.style){
        if (typeof document.documentElement.style.maxHeight != "undefined") {
        document.write('あなたがお使いのブラウザはIE7っぽいです');
        } else {
        document.write('あなたがお使いのブラウザはIE6っぽいです');
        }
    }else{
    document.write('あなたがお使いのブラウザはIE8っぽいです');
    }
}else{
document.write('ごめんなさい、あなたのブラウザを特定できませんでした');
}

以上、jQuery.supportに加えて、機能をサポートしているかどうかの条件文にのみこだわったブラウザの判別でした。IEの判別はまあまあ使えるでしょうか。それ以外のブラウザはサポートしている機能が同じなので、条件分岐させる必要もないことでしょう。