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