」工欲善其事,必先利其器。「—孔子《論語.錄靈公》
首頁 > 程式設計 > 讓我們建立一個簡單的 React hook 來偵測瀏覽器及其功能

讓我們建立一個簡單的 React hook 來偵測瀏覽器及其功能

發佈於2024-11-08
瀏覽:281

Let

使用者代理嗅探是最受歡迎的瀏覽器偵測方法。不幸的是,由於多種原因,前端開發不太容易使用它。瀏覽器供應商不斷嘗試讓嗅探變得不可能。因此,每個瀏覽器都有自己的使用者代理字串格式,解析起來非常複雜。

有一個更簡單的方法可以使用瀏覽器 CSS API 實現相同的目的,我將向您展示。那麼讓我們建立瀏覽器功能檢測 React hook。

我們將使用 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');
    // ...
}

我們將使用這個簡單的鉤子。這個鉤子接收一個包含support條件的字串,這是我們要驗證的CSS規則,例如顯示:彎曲。

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)
    ');
    // ...
}

使用CSS檢測用戶瀏覽器支援情況

為了偵測使用者瀏覽器,我們必須進行一些駭客攻擊。

瀏覽器駭客攻擊與違法行為無關。它只是一個特殊的 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() 更容易維護,而且更細粒度。它歡迎開發人員使用優雅降級或漸進增強方法並精細地應用補丁。

版本聲明 本文轉載於:https://dev.to/morewings/lets-create-a-simple-react-hook-to-detect-browsers-and-their-capabilities-4lnf?1如有侵犯,請聯絡study_golang@163 .com刪除
最新教學 更多>
  • 如何在信用記錄檢索中實現左連接?
    如何在信用記錄檢索中實現左連接?
    How to Perform Left Joins in Doctrine在函數 getHistory() 中,您嘗試擷取使用者的信用歷史記錄。但是,連接子句中的初始語法導致了錯誤。 要在 Doctrine 中執行左連接,可以使用以下語法:$qb ->select('a', 'u') ...
    程式設計 發佈於2024-11-08
  • 以下是幾種可能的標題:

1. How to Make CSS Transitions Work with `ngIf` in Angular 2?
2. Why Does `ngIf` Break My CSS Transitions in Angular 2?
3. Angular 2: Combining `ngIf` and CSS Animations for Smooth Trans
    以下是幾種可能的標題: 1. How to Make CSS Transitions Work with `ngIf` in Angular 2? 2. Why Does `ngIf` Break My CSS Transitions in Angular 2? 3. Angular 2: Combining `ngIf` and CSS Animations for Smooth Trans
    Angular 2 的 ngIf 和 CSS 過渡/動畫如何在 Angular 2 中使用 CSS 將 div 從右側滑入? <div class="note" [ngClass]="{'transition':show}" *ngIf="sh...
    程式設計 發佈於2024-11-08
  • 如何讓您的 React 應用程式更快:效能提示和最佳實踐
    如何讓您的 React 應用程式更快:效能提示和最佳實踐
    啊,反应!我们喜爱的用于构建 UI 的库。它就像一剂神奇的药剂,让我们的网络应用程序感觉具有交互性和快速性——直到有一天,它却没有了。突然,你注意到事情变慢了。点击按钮就像用信鸽寄信一样。您的应用程序从闪电般的速度变成了慢吞吞的速度,用户开始给您“看”。 但是别担心!就像咖啡可以解决大部分生活问题一...
    程式設計 發佈於2024-11-08
  • 帶有 go 工作區的 Golang 微服務模組化架構
    帶有 go 工作區的 Golang 微服務模組化架構
    可擴充的程式碼庫基礎設施 Golang 在後端開發、並發操作方面表現出色,是建立可擴展和高效能後端應用程式的完美套件。由於缺乏圍繞 Go 工作區的微服務架構的帖子,這是透過不同服務共享模組化程式碼的令人難以置信的工具,我決定分享我的實現。 項目設定 mkdir d...
    程式設計 發佈於2024-11-08
  • 如何在 C++0x 中使用初始化列表初始化成員數組?
    如何在 C++0x 中使用初始化列表初始化成員數組?
    使用初始值設定項目清單初始化成員陣列在C 0x 中,嘗試使用初始值設定項清單初始化成員陣列時,可能會遇到錯誤「賦值中的型別不相容」 .要解決此問題,請考慮使用可變參數範本建構子:struct foo { int x[2]; template <typename... T>...
    程式設計 發佈於2024-11-08
  • 如何在 AWS Lambda 函數中匯入 Pandas(庫) - AWS Lambda Layers
    如何在 AWS Lambda 函數中匯入 Pandas(庫) - AWS Lambda Layers
    假設您需要在 AWS Lambda 函數上執行 Python 腳本,然後收到此錯誤? { "errorMessage": "Unable to import module 'lambda_function': No module named 'pandas', "errorType": "...
    程式設計 發佈於2024-11-08
  • 將日期與 MySQL 的 DATE_FORMAT 進行比較時,為什麼使用相同的格式至關重要?
    將日期與 MySQL 的 DATE_FORMAT 進行比較時,為什麼使用相同的格式至關重要?
    與 MySQL DATE_FORMAT 進行日期比較使用 MySQL 的 DATE_FORMAT函數比較日期時,了解您選擇的格式會影響比較結果至關重要.在給定的示例中,表包含格式為“%d-%m-%Y”的日期,並且查詢嘗試使用相同的格式來比較它們。但是,這會導致不正確的結果,因為“28-10-2012...
    程式設計 發佈於2024-11-08
  • 如何在Android中實作帶有按鈕的自訂操作列?
    如何在Android中實作帶有按鈕的自訂操作列?
    在Android 中實現帶有自訂按鈕的自訂操作欄創建自訂ActionBar 可以實現應用程式使用者介面的個人化,提供視覺一致性和增強的使用者體驗。本指南將討論三個關鍵面向:1。建立自訂操作列視圖要在ActionBar 中合併自訂視圖,請依照下列步驟操作:擴充自訂佈局: 建立自訂操作欄佈局(例如,ac...
    程式設計 發佈於2024-11-08
  • 相同的 Python 字串何時以及為何共享或具有單獨的記憶體分配?
    相同的 Python 字串何時以及為何共享或具有單獨的記憶體分配?
    Python 的字串記憶體分配之謎Python 字串表現出一種奇怪的行為,即相同的字串可以共享記憶體或單獨儲存。了解這種行為對於優化 Python 程式中的記憶體消耗至關重要。 字串初始化和比較最初,具有相同字元的兩個字串(例如 a == b)通常共享內存,如下所示由它們相同的 id 值證明。然而,...
    程式設計 發佈於2024-11-08
  • 了解 PHP OOP 中的存取修飾符:公有、受保護和私有
    了解 PHP OOP 中的存取修飾符:公有、受保護和私有
    在 PHP 物件導向程式設計 (OOP) 中,存取修飾符控制類別屬性和方法的可見性。 PHP 中的主要存取修飾符是 public、protected 和 private。 本文將引導您了解這些存取修飾符的目的和用法,並解釋如何在 PHP OOP 中有效地應用它們。 1.公共存取修...
    程式設計 發佈於2024-11-08
  • 如何在Python中建立跨模組變數可存取性:共享變數而不共享實例?
    如何在Python中建立跨模組變數可存取性:共享變數而不共享實例?
    建立跨模組變數可訪問性在Python中,一個方便的跨模組變數是__debug__。然而,創建具有類似功能的自訂變數可能看起來具有挑戰性。本文深入研究這個主題,探索一種跨模組定義共享變數同時保持其不變性的方法。 解決方案:利用全域模組級變數建立如果跨模組變數不共用公共變數實例,請考慮使用全域模組級變數...
    程式設計 發佈於2024-11-08
  • 確保資料完整性:比較蘇打水和品質保證的遠大期望
    確保資料完整性:比較蘇打水和品質保證的遠大期望
    随着组织越来越依赖数据驱动的决策,数据质量变得至关重要。确保数据完整性不仅涉及数据可用性,还涉及数据的准确性、一致性和可靠性。为了实现这一目标,人们开发了各种工具,其中 Soda 和 Great Expectations 脱颖而出,成为流行的数据质量保证解决方案。本文将比较这两种工具,重点介绍它们的...
    程式設計 發佈於2024-11-08
  • 如何在自訂 PHP 函數中建立可選參數?
    如何在自訂 PHP 函數中建立可選參數?
    解讀 PHP 中的可選參數PHP 手冊使用括號來表示函數語法中的可選參數。例如,在 date() 函數中,$timestamp 參數是可選的,預設為 time()。 但是在定義自訂函數時我們要如何建立這樣的可選參數? 解開力學模擬手冊中的語法,我們在參數定義中使用等號(=):function dos...
    程式設計 發佈於2024-11-08
  • 如何使用 Display: None 消除 HTML 元素中的不可見空間?
    如何使用 Display: None 消除 HTML 元素中的不可見空間?
    從HTML 中刪除「看不見空格」在HTML 中,儘管將顯示屬性設為none,但仍出現空格,這可能是由換行符引起的。要解決此問題,請考慮以下解決方案:1.消除換行符:刪除 HTML 元素之間的所有換行符,建立單行程式碼。 2.註解掉換行符:在每個換行符之前和之後實現 HTML 註解以抑制其效果。例如:...
    程式設計 發佈於2024-11-08
  • 解鎖您的資料庫技能:&#新增學生個人資訊&#項目
    解鎖您的資料庫技能:&#新增學生個人資訊&#項目
    您準備好深入資料庫管理的世界並學習如何有效地儲存和操作學生資料了嗎? LabEx 提供的「新增學生個人資訊」專案就是您的最佳選擇,這是一門綜合性程式設計實作課程,將為您提供在該領域脫穎而出的必要技能。 在這個專案中,您將踏上掌握將學生個人資訊添加到資料庫的藝術的旅程。您將首先學習如何設定 MySQ...
    程式設計 發佈於2024-11-08

免責聲明: 提供的所有資源部分來自互聯網,如果有侵犯您的版權或其他權益,請說明詳細緣由並提供版權或權益證明然後發到郵箱:[email protected] 我們會在第一時間內為您處理。

Copyright© 2022 湘ICP备2022001581号-3