繁体   English   中英

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

[英]React - How to check if a specific font-face has been loaded?

假设我有一个像这样的字体:

@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 的无样式文本,尤其是在下载速度较慢的设备上,我想设置与 web 字体不同的后备字体样式。

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

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

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

其次,因为我可能在一个页面上有多个 web fonts,所以我想在特定的 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 字体并呈现到屏幕时继续应用回退样式。 只有在加载了所有 fonts 之后,样式才会发生变化。 这是意料之中的,因为我正在使用document.fonts.ready function。

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

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

正如其他人已经提到的, use-font-face-observer解决了这个问题。 我在一个项目中用 React + Vite 解决了我的问题:

首先,安装 package

npm install use-font-face-observer

假设您有这个 CSS:

@font-face {
  font-family: 'Roadgeek 2000 Series C';
  /* Rest of the styles... */
}

您必须在 jsx 代码中匹配该名称:

import useFontFaceObserver from 'use-font-face-observer';

export function SomeComponent() {
  const isFontLoaded = useFontFaceObserver([
    { family: 'Roadgeek 2000 Series C' }, // Same name you have in your CSS
  ]);

  useEffect(() => {
    console.log("Is font loaded?", isFontLoaded);
  }, [isFontLoaded]);

  return (
    // Your jsx goes here...
  )
}

在您的控制台中,您会看到类似这样的内容

Is font loaded? false
Is font loaded? true

当加载该字体时,该变量会自动更改。

我认为除了 CSS 之外,观察@font-face的最佳方法是使用 javascript。 查看这个小型库fontfaceobserver以及此博客以获取更多改进您的应用程序首先加载...。

而且,如果您正在使用 react,请确保使用useLayoutEffect ,因为在其他钩子(如useEffect中,字体已经加载并准备就绪,您应该能够在react之前访问它。

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

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

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM