キーポイント
昔々、ブラウザ検出はJavaScriptプログラマーの最高のスキルでした。一部の機能がIE5で機能しますが、Netscape 4では機能しないことがわかっている場合は、ブラウザをテストし、それに応じてコードを変更します。たとえば、
if (navigator.userAgent.indexOf('MSIE 5') != -1) { // 我们认为此浏览器是 IE5 }
しかし、私が最初に業界に参加したとき、武器競争はすでに始まっていました!ベンダーはユーザーエージェント文字列に追加の値を追加しているため、競合他社のブラウザや独自の値のように見えます。たとえば、これはMacのSafari 5です:
<code>Mozilla/5.0 (Macintosh; Intel Mac OS X 10_6_8) AppleWebKit/534.59.10 (KHTML, like Gecko) Version/5.1.9 Safari/534.59.10</code>
これらすべての値を追加する目的は、ブラウザ検出を回避することです。スクリプトがFirefoxのみが特定の機能を処理できると想定している場合、Safariは機能しても除外される場合があります。ユーザーがユーザーエージェントを自分で変更できることを忘れないでください。ブラウザを設定して「GoogleBot/1.0」を認識して、サイト所有者がクロールのみを使用すると思うものにアクセスできるようにしました。
したがって、時間が経つにつれて、この種のブラウザの検出は不可能な混乱になり、ほとんどが使用されていないため、より良いものに置き換えられています。
機能検出は、使用する機能をテストするためだけです。たとえば、
(ビューポートに対する要素の位置を取得する)が必要な場合、ブラウザではなく、ブラウザがサポートされるかどうかが重要ですテスト機能自体よりも悪い:getBoundingClientRect
この関数をサポートしていないブラウザは、「未定義の」タイプを返すため、条件は渡されません。特定のブラウザでスクリプトをテストすることなく、正しく機能するか、静かに失敗することがわかります。
しかし、真実は - 機能検出が完全に信頼できるわけではありません - 時には失敗することがあります。それでは、今すぐいくつかの例を見て、各ケースを解決するためにできることを見てみましょう。
おそらく、機能検出障害の最も有名な例は、インターネットエクスプローラーでのAJAX要求のActiveXObjectをテストすることです。
ActiveXは後期のオブジェクトの例であり、実際的に重要なのは、を使用しようとするまで
if (navigator.userAgent.indexOf('MSIE 5') != -1) { // 我们认为此浏览器是 IE5 }
これを修正するには、例外ハンドリングを使用する必要があります - オブジェクトをインスタンス化する必要がありますcatch fielures>それに応じて処理します。
<code>Mozilla/5.0 (Macintosh; Intel Mac OS X 10_6_8) AppleWebKit/534.59.10 (KHTML, like Gecko) Version/5.1.9 Safari/534.59.10</code>
の要素がDraggable APIをサポートするかどうかを確認します。
[draggable="true"]
if (typeof document.documentElement.getBoundingClientRect != "undefined") { // 浏览器支持此函数 }
が非常に混乱している理由です。なぜなら、プロパティをまったく返すのではなく、DOMプロパティを返すからです。
これは、getAttribute
属性を既に持っている要素を使用する場合を意味します:
それから、それらがサポートされていなくても、IE8以前はに対して
を返します。if (typeof window.ActiveXObject != "undefined") { var request = new ActiveXObject("Microsoft.XMLHTTP"); }
属性は何でもできます:true
("draggable" in element)
に対して
を返します。if (typeof window.ActiveXObject != "undefined") { try { var request = new ActiveXObject("Microsoft.XMLHTTP"); } catch (ex) { request = null; } if (request !== null) { //... 我们有一个请求对象 } }
この場合、解決策は、テストの属性を持たない要素を使用することです。最も安全な方法は、作成された要素を使用することです。
true
ユーザーの動作に関する仮定("nonsense" in element)
if ("draggable" in element) { // 浏览器支持拖放 }
の
誤差に由来します。しかし、タッチスクリーンラップトップはどうですか?ユーザーは画面に触れているか、上記のコードを使用できないため、マウスでクリックすることは何も実行できません。<div draggable="true"> ... </div>
を使用して、タッチがクリックを生成するのを防ぎます。
if (navigator.userAgent.indexOf('MSIE 5') != -1) { // 我们认为此浏览器是 IE5 }
これが苦痛であることを認めるが、テストする必要がないことは機能ではないことがあります - ではなく、ブラウザ - 特定のブラウザが機能しないものをサポートすると主張しているためです。最近の例は、Opera 12のsetDragImage()
です(オブジェクトをドラッグアンドドロップする方法です)。 dataTransfer
<code>Mozilla/5.0 (Macintosh; Intel Mac OS X 10_6_8) AppleWebKit/534.59.10 (KHTML, like Gecko) Version/5.1.9 Safari/534.59.10</code>
を試してカスタムドラッグイメージを追加し、デフォルト値をサポートなしで喜んで保持したい場合(これは起こります)、これは問題ないかもしれません。ただし、アプリケーションがカスタム画像が必要な場合は、まったく異なる実装を使用する必要があるように(つまり、カスタムJavaScriptを使用してすべてのドラッグ動作を実装)する必要がある場合はどうなりますか?
またはブラウザが特定の機能を実装しているが、避けられないレンダリングエラーがある場合はどうなりますか?問題のあるブラウザを明示的に検出し、使用をサポートしようとした機能から除外する以外に選択肢がない場合があります。
問題は、ブラウザ検出を達成するための最も安全な方法は何ですか?
2つの提案があります
新しいブラウザがリリースされた場合、テスト結果が変更される可能性は低いため、標準オブジェクトの代わりに独自のオブジェクトを使用する方が良いです。これが私のお気に入りの例のいくつかを紹介します:window.opera
if (typeof document.documentElement.getBoundingClientRect != "undefined") { // 浏览器支持此函数 }
ユーザーエージェントの文字列は信頼できない混乱であることに気付きましたが、ベンダーの文字列は実際には非常に予測可能であり、ChromeまたはSafariを確実にテストするために使用できます。
if (typeof window.ActiveXObject != "undefined") { var request = new ActiveXObject("Microsoft.XMLHTTP"); }
これらすべての黄金律は非常に注意することです。可能な限り多くのブラウザで条件をテストし、順方向の互換性を慎重に検討してください。目標は、ブラウザの条件を使用して
ブラウザを除外することです。既知の機能(これは機能テストの目的です)if (typeof window.ActiveXObject != "undefined") { try { var request = new ActiveXObject("Microsoft.XMLHTTP"); } catch (ex) { request = null; } if (request !== null) { //... 我们有一个请求对象 } }
基本的に、機能テストが完全に一致していると常に仮定します - これが当てはまらないことがわからない限り、機能は予想どおりに機能します。
if ("draggable" in element) { // 浏览器支持拖放 }
を選択します
終了する前に、オブジェクトとプロパティテストに使用できるさまざまなタイプの構文をチェックしたいと思います。たとえば、近年、次の構文が一般的になりました。 IE5とその同様の製品が構文のためにエラーを投げるため、過去に使用することはできませんでした。 本質的に、それは次のものとまったく同じですが、書く方が短いです:
テスト)の早い段階で使用しました。これは、オブジェクトの評価方法のために安全です - 定義されたオブジェクトまたは関数は常に真であると評価され、定義されていない場合、偽として評価されます。 属性は、IE6を除外するために時々使用されることがあります:if (navigator.userAgent.indexOf('MSIE 5') != -1) {
// 我们认为此浏览器是 IE5
}
<code>Mozilla/5.0 (Macintosh; Intel Mac OS X 10_6_8) AppleWebKit/534.59.10 (KHTML, like Gecko) Version/5.1.9 Safari/534.59.10</code>
if (typeof document.documentElement.getBoundingClientRect != "undefined") {
// 浏览器支持此函数
}
window.opera
style.maxWidth
if (typeof window.ActiveXObject != "undefined") {
var request = new ActiveXObject("Microsoft.XMLHTTP");
}
属性maxWidth
がサポートされ、に著者が定義された値を持っている場合にのみTrueに評価されます。したがって、このようなテストを書くと、失敗する可能性があります。
if (typeof window.ActiveXObject != "undefined") { try { var request = new ActiveXObject("Microsoft.XMLHTTP"); } catch (ex) { request = null; } if (request !== null) { //... 我们有一个请求对象 } }
これの詳細については、現実世界での自動タイプ変換を参照してください。
JavaScript機能検出に関するよくある質問
JavaScript機能の検出とは何ですか?なぜそれが重要なのですか?javaScript機能検出は、いくつかの理由で失敗する場合があります。よくある理由は、機能検出コードが誤って実装されていることです。たとえば、コードがオブジェクトに存在しないプロパティをチェックすると、未定義に戻り、偽ネガになります。もう1つの理由は、ブラウザの癖やエラーである可能性があります。これにより、機能検出が不正確な結果をもたらす可能性があります。
機能検出には、ユーザーのブラウザが特定の機能をサポートするかAPIをサポートするかどうかを確認し、ブラウザー検出はユーザーのブラウザとバージョンを認識します。どちらの手法も互換性と機能を確保するように設計されていますが、ブラウザの種類やバージョンに基づいてサポートを想定するのではなく、機能を直接チェックするため、機能の検出はより良い練習と見なされることがよくあります。
JavaScriptのnavigator.userAgent
属性を使用して、モバイルデバイスを検出できます。このプロパティは、ブラウザのユーザーエージェントヘッダーを表す文字列を返します。この文字列の特定のキーワード(「Android」、「iPhone」、「iPad」など)をチェックすることにより、ユーザーがモバイルデバイスにいるかどうかを判断できます。
feature.jsは、機能検出のための軽量で高速でシンプルなJavaScriptユーティリティです。使用者がブラウザが特定の機能をサポートするかどうかをテストできるようにする使いやすいAPIを提供します。これにより、サポートされていない機能のバックアップソリューションまたは代替ソリューションを提供することで、Webサイトまたはアプリケーションの互換性と機能を強化します。
Modernizrは、開発者が古いブラウザーとの互換性を維持しながら、開発者がHTML5およびCSS3機能を活用するのに役立つJavaScriptライブラリです。機能検出を使用して、ブラウザが特定の機能をサポートし、HTML要素にクラスを追加するかどうかを確認し、StyleSheetsまたはJavaScriptの特定のブラウザ機能を見つけることができます。
Device-Detector-JSパッケージは、デバイス検出のための強力なツールです。ユーザーエージェントの文字列を解析し、スマートフォン、タブレット、デスクトップ、テレビ、その他のデバイスを検出します。また、ブラウザ、エンジン、オペレーティングシステム、およびその他の有用な情報を検出します。このパッケージを使用して、検出されたデバイスに基づいてWebサイトまたはアプリケーションの動作を調整できます。
機能検出は、ウェブサイトのパフォーマンスを改善するのに役立ちますか?
さまざまなブラウザでサポートされている最新の機能を理解する方法は?
以上がJavaScript機能の検出が失敗したときの詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。