Прослушивание пользовательского агента — самый популярный подход к обнаружению браузера. К сожалению, он не очень доступен для фронтенд-разработки по нескольким причинам. Производители браузеров постоянно пытаются сделать сниффинг невозможным. Таким образом, каждый браузер имеет свой собственный формат строки пользовательского агента, который очень сложен для анализа.
Есть гораздо более простой способ добиться того же с помощью CSS API браузера, который я собираюсь вам показать. Итак, давайте создадим крючок React для обнаружения возможностей браузера.
Мы собираемся использовать статический метод CSS.supports(). Он возвращает логическое значение, указывающее, поддерживает ли браузер данную функцию CSS или нет. Это javascript-аналог @supports at-rule. Он работает аналогично медиа-запросам, но с использованием возможностей 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, которое мы собираемся проверить, например дисплей: гибкий.
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; };
Теперь мы можем проверить поддержку различных функций CSS изнутри компонента React. Вот ссылка на 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 или селектор, который работает по-разному в одном из доступных браузеров.
Вот справочная страница с различными хаками браузера. После тщательных экспериментов на своей машине я выбрал следующее:
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