ブラウザを判定する(ブラウザスニッフィング)
はじめに
ブラウザをユーザーエージェントの使用なしに、ブラウザの固有動作を元に判定します。
これは、ユーザーエージェント偽装などへの対策として優秀です。また、今後のブラウザの増加などで意図せずユーザーエージェント文字列の衝突による誤判定を防ぐこともできます。(ただし、動作の変更により問題が発生する可能性があります)
ブラウザを判定する
ua.jsvar ua = (function() {
return {
IE: /*@cc_on!@*/false || !!document.documentMode, // IE4-11
// Trident:!!document.uniqueID, // IE, Edge Legacy (EdgeHTML)
Gecko: 'MozAppearance' in document.documentElement.style,
// Firefox*
WebKit: Object.prototype.toString.call(window.HTMLElement).indexOf('Constructor') > 0 || (!window.chrome && 'webkitAudioContext' in window),
// Safari, iOS Third Party Browser, Chrome27-
Blink: !!window.chrome, // Chromium (Chrome28+, Edge, ...)
// Presto: !!window.opera, // Opera12-
Mobile: 'orientation' in window,
Touch: 'ontouchstart' in document
};
})();
機能毎に判定する
特定の機能に対応しているか否かは、ブラウザ単位で判定すべきではありません。機能単位で実装有無を確認して個別に対応すべきです。
if (window.requestAnimationFrame) {
window.requestAnimationFrame(function() {
// ...
});
}
if (window.requestIdleCallback) {
window.requestIdleCallback(function() {
// ...
});
}
@supports (display: grid) {
div {
display: grid;
}
}
※@supports
は、 Firefox22+, Safari9+, Chrome28+ で利用可能です。
@supports - CSS: カスケーディングスタイルシート | MDN
※ CSS によるブラウザ判定は、本記事の主題ではないため、簡略します。
IE を判定する
// IE4-10
/*@cc_on!@*/false
// IE8-11 (EmulateIE5,7-11)
!!document.documentMode
// IE4-11
/*@cc_on!@*/false || !!document.documentMode
@cc_on
@cc_on ~ @
は、条件付きコンパイル機能を有効にする記述です。
条件付きコンパイルは、 JScript の機能でバージョン毎に互換性を維持しながら JScript の新機能を使用するための機能です。 IE4 (JScript 3.0) で登場して、 IE11 で廃止された。当然ながら、 IE 以外では実装されていません。
/*@cc_on!@*/
は、!
(否定)の処理を実行するという意味です。 そのため、/*@cc_on!@*/false
は!false
となり。対応ブラウザではtrue
として処理されます。非対応ブラウザでは、/*@cc_on!@*/
はコメント扱いであるため、false
として処理されます。
※対応時期については、諸説あるようです(IE10-, IE4-10)
document.documentMode
document.documentMode
は、 IE8 で実装されたドキュメントモードの機能です。ドキュメントモードで指定したバージョンの IE でエミュレートしてウェブページを表示します。
IE5,7-11 をエミュレートできます。
ドキュメントモードの指定は、<meta http-equiv="X-UA-Compatible">
を使用してください。
※document.documentMode
は、ブラウザのバージョンではありません。
エミュレート中のドキュメントモードのバージョンです。
※ Edge Legacy は、document.documentMode
に非対応です。
<meta http-equiv="X-UA-Compatible">
は、対応しています。
※ Windows10 以降では、ドキュメントモードは非推奨です。
※ドキュメント モードとエンタープライズ モード | Microsoft Learn
※IE対策の「X-UA-Compatible:IE=edge」は必要か?
Trident を判定する
// IE, Edge Legacy
!!document.uniqueID
// IE4-11, Edge Legacy
/*@cc_on!@*/false || !!document.uniqueID
※「Trident」は、 IE, Edge Legacy のレタリングエンジンの名称です。
document.uniqueID の対応時期
正確な対応時期は不明だが、 IE9 で実装済みであることは次ソースからうかがえる。実際はそれよりもまえに実装されているものと考えられます。
Gecko 判定について
// Firefox *
var isFF = 'MozAppearance' in document.documentElement.style;
// Firefox 1.5+
var isFF = typeof InstallTrigger !== "undefined";
※「Gecko」は、Firefox と派生ブラウザのレタリングエンジンの名称です。
※window.InstallTrigger
は、 Firefox の旧拡張機能をウェブページからインストールするための機能です。WebExtension(新拡張機能)には対応していません。現在は、初期設定でnull
初期化されており、使用することはできません。いつなくなってもおかしくない機能です。
1754441 - Deprecate InstallTrigger
WebKit を判定する
// Safari9-, Chrome27-
Object.prototype.toString.call(window.HTMLElement).indexOf('Constructor') > 0
// Safari3.1+
!window.chrome && 'webkitAudioContext' in window
※ WebKit は、現在主に Safari / iOS Third Party Browser で使用されています。
'WebkitAppearance' in document.documentElement.style
var isWebKit = !window.chrome && 'WebkitAppearance' in document.documentElement.style;
この方法は既に利用できません。Firefox 64+ が-webkit-appearance
に対応したことにより WebKit の判定として機能していません。
/constructor/i.test(window.HTMLElement)
// Safari9-
var isSafari = /constructor/i.test(window.HTMLElement);
var isSafari = Object.prototype.toString.call(window.HTMLElement).indexOf('Constructor') > 0;
この方法は、既に利用できません。 Safari10 から機能していません。
Blink を判定する
Blink は、 WebKit のフォークです。そのため、古いバージョンの Chromium 系のブラウザは、 WebKit として判定されます。
※ Chrome 28 以降 Blink が使用されています。
Presto を判定する
※「Presto」は、Opera 12 までのレタリングエンジンの名称です。
※ Opera は、Opera 14 から Chromium ベースで開発されているため、 Blink で判定します。