ユーザー エージェント スニッフィングは、ブラウザ検出の最も一般的なアプローチです。残念ながら、さまざまな理由により、フロントエンド開発にとってはあまりアクセスしにくいものです。ブラウザ ベンダーは常にスニッフィングを不可能にしようとしています。したがって、各ブラウザには独自のユーザー エージェント文字列形式があり、解析が非常に複雑です。
ブラウザ CSS API を使用して同じことを実現する、より簡単な方法がありますので、それを紹介します。それでは、ブラウザ機能検出 React フックを作成しましょう。
CSS.supports() 静的メソッドを使用します。ブラウザーが特定の CSS 機能をサポートしているかどうかを示すブール値を返します。これは @supports at-rule に似た JavaScript です。メディア クエリと同様に機能しますが、CSS 機能が主題となります。
コンポーネントのレンダリング サイクル中に CSS.supports() を呼び出すという最も単純なアプローチでは、Next.js などのサーバー サイド レンダリング環境で問題が発生します。サーバー側レンダラはブラウザ API にアクセスできないため、コード文字列を生成するだけです。
import type {FC} from 'react'; const Component: FC = () => { // ? Don't do this! const hasFeature = CSS.supports('your-css-declaration'); // ... }
代わりにこの単純なフックを使用します。フックは、サポート条件、つまり検証する CSS ルールを含む文字列を受け取ります。表示: flex.
import {useState, useEffect} from 'react'; export const useSupports = (supportCondition: string) => { // Create a state to store declaration check result const [checkResult, setCheckResult] = useState(); useEffect(() => { // Run check as a side effect, on user side only setCheckResult(CSS.supports(supportCondition)); }, [supportCondition]); return checkResult; };
これで、React コンポーネント内からさまざまな CSS 機能のサポートを確認できるようになりました。 MDN @supports リファレンスは次のとおりです
import type {FC} from 'react'; const Component: FC = () => { // Check for native `transform-style: preserve` support const hasNativeTransformSupport = useSupports(' (transform-style: preserve) '); // Check for vendor prefixed `transform-style: preserve` support const hasNativeTransformSupport = useSupports(' (-moz-transform-style: preserve) or (-webkit-transform-style: preserve) '); // ... }
ユーザーのブラウザを検出するには、ちょっとしたハッキングを行う必要があります。
ブラウザのハッキングは法律違反とは何の関係もありません。これは、利用可能なブラウザの 1 つで動作が異なる単なる特別な CSS 宣言またはセレクターです。
ここに、さまざまなブラウザハックが記載されたリファレンス ページがあります。私のマシンで徹底的に実験した結果、次のものを選択しました:
const hacksMapping = { // anything -moz will work, I assume firefox: '-moz-appearance:none', safari: '-webkit-hyphens:none', // tough one because Webkit and Blink are relatives chrome: ' not (-webkit-hyphens:none)) and (not (-moz-appearance:none)) and (list-style-type:"*"' }
そして、最後のフックは次のようになります:
export const useDetectBrowser = () => { const isFirefox = useSupports(hacksMapping.firefox); const isChrome = useSupports(hacksMapping.chrome); const isSafari = useSupports(hacksMapping.safari); return [ {browser: 'firefox', condition: isFirefox}, {browser: 'chromium based', condition: isChrome}, {browser: 'safari', condition: isSafari}, ].find(({condition}) => condition)?.browser as 'firefox' | 'chromium based' | 'safari' | undefined; };
これがフックの完全に動作するデモです。
これが完璧で安定したアプローチであるとは言えません。ブラウザは更新され、ベンダーのプロパティは標準によって放棄されたり、置き換えられたりすることが非常に頻繁にあります。同時に、ユーザー エージェント スニッフィングについても次のことが言えます。どちらの方法でも同様の問題があります。ただし、CSS.contains() の方が保守が簡単で、より粒度が細かいです。開発者がグレースフル デグラデーションまたはプログレッシブ エンハンスメント アプローチを使用し、パッチをきめ細かく適用することを歓迎します。
免責事項: 提供されるすべてのリソースの一部はインターネットからのものです。お客様の著作権またはその他の権利および利益の侵害がある場合は、詳細な理由を説明し、著作権または権利および利益の証拠を提出して、電子メール [email protected] に送信してください。 できるだけ早く対応させていただきます。
Copyright© 2022 湘ICP备2022001581号-3