确保网页字体加载完成

ts
const fonts = [
  {
    isLoaded: false,
    name: 'JetBrainsMono',
  },
  {
    isLoaded: false,
    name: 'SmileySans',
  },
]

interface LoadingDoneEvent extends Event {
  fontfaces: FontFace[]
}

export default async (): Promise<void> => {
  return new Promise((resolve) => {
    document.fonts.addEventListener('loadingdone', (event: Event): void => {
      ;(event as LoadingDoneEvent).fontfaces // 网速快的话,可能返回多个,慢的话有可能只返回一个
        .map((f) => f.family)
        .forEach((name) => {
          const font = fonts.find((f) => name.includes(f.name))
          if (font) {
            font.isLoaded = true
          }
        })
      if (fonts.every((f) => f.isLoaded)) {
        resolve()
      }
    })
  })
}

注意

document.fonts.ready resolve 的时候,只保证字体已经注册,并不是已经加载完成。

网页的字体是按需加载的,有的字体暂时没用到,是不会加载的

比如页面使用到了某中文字体,但是页面一个中文都没有,那个中文字体文件就不会加载。

但是我们可以通过 link 标签进行预加载,比如:

html
<link as="font" crossorigin="" href="****.woff2" media="screen and (max-width: 480px)" rel="preload" type="font/woff2">