React - 如何检查是不是已加载特定的字体?

Posted

技术标签:

【中文标题】React - 如何检查是不是已加载特定的字体?【英文标题】:React - How to check if a specific font-face has been loaded?React - 如何检查是否已加载特定的字体? 【发布时间】:2021-06-26 23:19:42 【问题描述】:

假设我有这样的字体:

@font-face 
    font-family: 'MyGreatFont';
    src: url(~"./font/greatfont.woff2") format('woff2'),
        url(~"./font/greatfont.woff") format('woff');
    font-weight: 600;
    font-style: normal;

在我使用它的地方,我会这样做:font-family: 'MyGreatFamily', san-serif

为了避免无样式文本的 Flash,尤其是在下载速度较慢的设备上,我希望后备字体的样式与我的网络字体不同。

为此,我有几个问题。我已经阅读了document.fonts 及其方法checkreadyonloadingdone

首先,我不太确定要给document.fonts.check 提供什么参数,以便在我的页面完全加载后返回true。我试过check('MyGreatFont')check('600 MyGreatFont')check('1em MyGreatFont'),甚至试过计算出的字体大小值:check('19.2px MyGreatFont)

全部返回false(这是不对的,因为我知道我的页面已完全加载了正在应用的网络字体)或错误:Uncaught DOMException: Failed to execute 'check' on 'FontFaceSet': Could not resolve 'Niche' as a font.

其次,由于我可能在一个页面上有多种 Web 字体,我想在特定 Web 字体可用时应用我的特殊样式。有没有办法做到这一点?

到目前为止,我有:

const MyPageComponent = () => 
    const [webFontsLoaded, setWebFontsLoaded] = useState(false)

    useEffect(() => 
        async function areFontsReady() 
            await (document as any).fonts.ready
            setWebFontsLoaded(true)
        

        areFontsReady()
    )

    return (
        <div className=`$webFontsLoaded ? 'web-fonts-styling' : 'fallback-font-styling'`>
            Content here
        </div>
    )

但这样做的目的是在未加载 webfont 时正确应用后备样式,但在加载 web 字体并将其呈现到屏幕时继续应用后备样式!只有在加载所有字体后,样式才会更改。这是意料之中的,因为我使用的是document.fonts.ready 函数。

有没有办法重复调用check 函数(使用正确的参数!)以便我知道何时切换样式?

注意:我希望在不使用第三方库(包括 JQuery、Font Face Observer 等)的情况下实现此行为

【问题讨论】:

您可以改用font-display 属性,无需从头开始构建。 啊,这很酷。我不知道font-display 属性。话虽如此,如果我在font-face 上放置了font-display: fallback,我将如何设置后备文本的样式,比如使用不同的字体大小和字体粗细,然后在下载网络字体时删除这些样式? 【参考方案1】:

use-font-face-observer 对此有一个钩子

const webFontsLoaded = useFontFaceObserver([family: `MyGreatFont`]);

https://www.npmjs.com/package/use-font-face-observer

【讨论】:

【参考方案2】:

我认为观察@font-face 除了CSS 的最佳方式是使用javascript。查看这个小型库 fontfaceobserver 以及此博客以了解更多 improve-your-app-first-load-by...。

如果你使用 react 确保使用 useLayoutEffect,因为在 useEffect 等其他钩子中,字体已经加载并准备就绪,你应该能够在 react 本身之前访问它。

【讨论】:

以上是关于React - 如何检查是不是已加载特定的字体?的主要内容,如果未能解决你的问题,请参考以下文章

MFC Treeview:如何检查 Treeview 是不是已经包含特定的子节点?

ReactNative:如何检查用户是不是已授予 gps 权限

如何使用 Detox 在 React Native 中检查是不是选择或禁用了特定元素?

React Native:如何检查是不是已授予地理定位权限

离子服务命令卡在“ [react-scripts] 文件已成功发出,等待类型检查结果...”

如何检查用户是不是已在 React Native Android 中授予相机权限?