記事の一部を大まかに翻訳しましたが、誤解があるかもしれません。修正してください。コメントセクションでの議論も読む価値があることは言及する価値があります。
機能検出
当初、フロントエンド エンジニアは、ユーザー エージェント スニッフィングのような方法は、これは未来のものではないため、非常に悪いものであると信じていました。プルーフコードはブラウザの新しいバージョンに適応できません。より良いアプローチは、次のように特徴検出を使用することです:
if (navigator.userAgent.indexOf("MSIE 7") > -1){
//何かをします
}
より良い方法は次のとおりです:
if(document.all){
/ /do something
}
2 つのメソッドは同じではありません。前者はブラウザの特別な名前とバージョンを検出するものであり、後者はブラウザの特性を検出するものです。 UA スニッフィングはブラウザのタイプとバージョン (少なくともブラウザのタイプ) を正確に取得できますが、機能検出はブラウザが特定のオブジェクトを所有しているかどうか、または特定のメソッドをサポートしているかどうかを判断します。この 2 つはまったく異なるものであることに注意してください。
機能の検出はブラウザが対応しているかどうかに依存するため、新しいバージョンのブラウザが登場した場合には面倒な確認作業が必要となります。たとえば、DOM 標準が初めて登場したとき、すべてのブラウザが getElementById() メソッドをサポートしていたわけではないため、最初のコードは次のようになります。
if(document.getElementById){ //DOM
element = document.getElementById(id)
} else if (document .all) { //IE
element = document.all[id];
} else if (document.layers){ //Netscape
element = document.layers[id]; 🎜>}
これは、機能検出の良い例です。注目すべき点は、他のブラウザーが getElementById() メソッドのサポートを開始しても、コードを変更する必要がないことです。
混合メソッド
その後、フロントエンド エンジニアは改善された書き方を検討し、コードは次のように変更されました。
//AVOID!!!
if (document.all) { //IE
id = document.uniqueID; 🎜>} else {
id = Math .random();
}
このコードの問題は、document.all 属性を検出して IE であるかどうかを判断することです。 IE を識別するときは、プライベート document.uniqueID プロパティが使用されると想定しても問題ありません。ただし、現在行われているのは document.all がサポートされているかどうかを判断するだけであり、ブラウザーが IE であるかどうかは識別しません。 document.all をサポートするだけでは、document.uniqueID が使用可能になるわけではありません。
その後、上の行を次の行に置き換えて、次のように書き始めました。
var isIE = navigator.userAgent.indexOf("MSIE") >
//次の行は置き換えられました。上記の行
var isIE = !!document.all; これらの変更は、「UA スニッフィングを使用しない」ことについて誰もが誤解していることを示しています。ブラウザの詳細情報は検出されなくなりましたが、機能サポートを通じて推測されます。ブラウザの機能に基づいて検出するこの方法は非常に不適切です。
その後、フロントエンドは document.all が信頼できないことを発見し、IE を検出するより良い方法は次のようになりました。
var isIE = !!document.all && document.uniqueID; この実装は間違っていました。ブラウザーによって追加された機能サポートを特定するには時間と労力がかかるだけでなく、他のブラウザーが同じ機能のサポートを開始するかどうかを確信することも不可能です。
このようなコードは広く使用されていないと思われる場合は、Mootools の古いバージョンのコード スニペットを見てください:
//MooTools 1.1.2 より
if (window.ActiveXObject) window.ie = window[window.XMLHttpRequest ? ie6'] = true;
else if (document.childNodes && !document.all && !navigator.taintEnabled) window.webkit = window[window.xpath ? 'webkit420' : 'webkit419'] = true; else if ( document.getBoxObjectFor != null || window.mozInnerScreenX != null) window.gecko = true;
特徴検出がどのように使用されるかに注目してください。 window.ie を検出することで ie8 を ie7 と間違えるなど、一連の問題を指摘できます。
その後
ブラウザの急速な発展に伴い、機能検出の使用はますます困難になり、信頼性も低くなりました。ただし、Mootools 1.2.4 では、引き続きこのメソッド (例: getBoxObjectFor()) が使用されます。
//MooTools 1.2.4 より
var Browser = $merge({
エンジン: {name: 'unknown', version: 0},
プラットフォーム: {name: (window.orientation != unknown) ? 'ipod' : (navigator.platform .match( /mac|win|linux/i) || ['other'])[0].toLowerCase()},
機能: {xpath: !!(document.evaluate), air: !!( window.runtime )、クエリ: !!(document.querySelector)}、
プラグイン: {}、
エンジン: {
presto: function(){
return (!window.opera) ? false : ( (arguments.callee.caller) ? 960: ((document.getElementsByClassName) ? 950: 925)); ((window.XMLHttpRequest)? ((document.querySelectorAll)? 6:5):4);機能.xpath) ? ((ブラウザ.機能.クエリ) ? 525 : 420) : 419); mozInnerScreenX == null) ? false: ((document.getElementsByClassName) ? 19 : 18);
特徴検出は避けるべき方法ですが、直接特徴検出は優れた方法であり、ほとんどの場合ニーズを満たすことができます。一般に、それらの関係を考慮せずに、テスト前にこの機能が実装されているかどうかを知るだけで十分です。
ブラウザの機能検出を決して使用しないと言っているのではなく、UA スニッフィングにはまだ多くの用途があると信じているためですが、正当な用途が多くあるとは思えません。 UA スニッフィングを検討している場合は、まずこのアイデアを実装してください。唯一の安全な方法は、特定のブラウザの特定のバージョンをターゲットにすることであり、それを超えるもの (新しいブラウザ バージョンなど) は信頼できません。実際、これは賢明なアプローチでもあります。不確実な新しいバージョンとの前方互換性と比較して、古いバージョンとの下位互換性が最も簡単な方法だからです。