簡體   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