JSでブラウザを判別してみよう ― 2010年11月25日 05時07分32秒
油断してたらまた4ヶ月も更新してなかったのだが、なんとなくJSでブラウザ判別を行うという、わりとありがちな事に挑戦してみる。
ライブラリとしてまとめようと思ってたんだけど、そろそろ眠いので、今日のところは断片的な記述にしておこう。
何を判別する?
メジャーどころだったらたいていはレンダリングエンジン≒ブラウザが成立しそうなもんなんだけど、WebKitの場合はSafariとChromeの両方がなかなか普及してるので、「レンダリングエンジンが何であるか」と「ブラウザが何であるか」の2種類を判別することにする。で、Safari/Chromeの場合はモバイル版かどうかも見ないとね。
ということで、レンダリングエンジンは
- Trident
- Gecko
- Presto
- WebKit
- IE
- Firefox
- Opera
- Safari
- Chrome
まずは、Presto = Opera。
めちゃくちゃ手抜きなんだけど、window.operaがundefinedじゃなければPrestoっつーことで。しかもPrestoだったら何も考えずにOperaっつーことで。
<button type="button" onclick="alert(!! window.opera)">レンダリングエンジンははPresto?</button>
<button type="button" onclick="alert(!! window.opera)">ブラウザはOpera?</button>
次はGecko = Firefox。
まぁ、GeckoをみんなFirefoxとみなすのは乱暴なのはわかってるんだけども、こちらも手抜き。
昔、MooToolsの1.2.2のブラウザ判定部分のソース見たときは、window.document.getBoxObjectForがundefinedでなければGeckoてな判断してたみたいなんだけど、Firefox 3.6の環境で試したらこれが成立しなくなってたのでwindowのプロパティを総当りで調べたところ、window.mozInnerScreenXあたりが使えそうなので組み合わせで判別してみる。
<button type="button" onclick="alert(window.document.getBoxObjectFor != undefined || window.mozInnerScreenX != undefined);">レンダリングエンジンはGecko?</button>
<button type="button" onclick="alert(window.document.getBoxObjectFor != undefined || window.mozInnerScreenX != undefined);">ブラウザはFirefox?</button>
IEかどうか、までは簡単。
IEかどうかを判別するのは、window.ActiveXObjectをチェックするのが定番なんだけども、念のためMSDNを見てみたら、なんかIE9で廃止になっちゃいそうな記述が。
びっくりしてIE9ベータで確認したらnullは返してこなかったんだけど、ちょっと怖いのでもうひとつの定番「window.document.all」を使うことに。でもこれ、Operaも実装してるんだったよな、確か。 っつーことで、こんな感じに。
<button type="button" onclick="alert(!!((window.ActiveXObject || window.document.all) && !window.opera))">レンダリングエンジンはTrident?</button>
IEのバージョンは細かく見てみたい。
で、IEの場合は他のブラウザよりもバージョンの違いをなるべく厳密に判別したくなるので、
- IE6よりも前
- IE6
- IE7
- IE8
- IE9
Another IE version detector snippetなるほど、styleプロパティでチェックするのね。ただこのサンプルどおりbody.styleをチェックする方法だとページロードが完了しないと判定できないので不便なので、head要素でチェックをしてみることに。あ、あとIE9かどうかの判別はwindow.msPerformanceでチェックしたほうがよさげ。
function getIEVersion(odoc){
if (odoc.body.style.scrollbar3dLightColor!=undefined)
{
if (odoc.body.style.opacity!=undefined) {return 'IE9';}
else if (odoc.body.style.msBlockProgression!=undefined) {return 'IE8';}
else if (odoc.body.style.msInterpolationMode!=undefined) {return 'IE7';}
else if (odoc.body.style.textOverflow!=undefined) {return 'IE6'}
else {return 'IE5.5 or lower';}
}
}
で、こんなコードを実行して、
<script type="text/javascript"> window.detected_ie_name = (function() { if(window.ActiveXObject == undefined && window.document.all == undefined) return "IEじゃない"; if(window.msPerformance != undefined) return "IE9"; var h = document.getElementsByTagName("head")[0]; if(h.style.msBlockProgression != undefined) return "IE8"; if(h.style.msInterpolationMode != undefined) return "IE7"; if(h.style.textOverflow != undefined) return "IE6"; return "IE5.5かそれ以前"; })(); </script>こんな感じのボタンを貼ってみる。
<button type="button" onclick="alert(window.detected_ie_name)">IEのバージョンは?</button>
WebKitか否か。
MooTools 1.2.2では、navigator.taintEnabledのチェックでもって判別してた。これなんぞ?と思ったら、よい解説が見つかった。
navigator.taintEnabled() というのは、「ユーザーに非通知でデータ送信が可能かどうか(データテイント機能の使用有無)を返すメソッド」です。「何それ?」て思われた方、ご安心ください。Netscape Navigator 3.x の時代の、古い古ーい仕様で、データテイント機能は現在使われておりません。多くのブラウザは、ただfalseを返すだけです。だそうで、まんま使わせてもらおう。
ただしSafari(WebKit)では、このメソッドそのものを定義していません。
<button type="button" onclick="try { alert(window.navigator.taintEnabled == undefined) } catch(e) { alert(false); }">レンダリングエンジンはWebKit?</button>って、IETester使ってるせいか、デフォルトIE以外だとwindow.navigator.taintEnabledにアクセスしただけで例外吐くのでtry catchで囲まなきゃ。
Safariか、Chromeか。
これはあんまりいい方法が見つからなかったので、両方でSafari5とChrome7の両方でwindowのプロパティを洗いざらい列挙してめぼしいところをいくつか試してみたところ、window.TouchListの有無がよさそうだった。
と思って今試したら、Safariでもwindow.TouchListがundefined返してきた。あれぇ?会社で試したときと違うなあ。
ということで、ちょっと別の方法探さなきゃ。ちなみにモバイル版かの判別は今のところwindow.orientationがNaNじゃなければモバイルってな判定でよさげ。
最近のコメント