字体动态载入问题

最近博客改用了思源字体,字体好看是好看,不过毕竟不是默认的字体,需要做动态载入(动态载入的教程可以看这个链接)。不过中文字体的体积比较大,如果客户端的操作系统上已经安装了思源的字体,那么就不需要再从服务器下载地址了。

首先我们需要检查客户端上是否已经安装了思源的字体。我们可以采用下面这个 gist 中提供的代码来做这个检测。

检测的原理是渲染两段文字,分别是使用 monospace 字体和目标字体,如果渲染出来字体的宽度一样,那么说明目标字体渲染失败了。这对于我们要用的思源字体是有效的。当然如果你用来检测其他的等宽英文字体可能会失败。

基于这个函数,我们可以在 head 中这么做:

1
2
3
4
5
6
7
8
9
<script>
function doesFontExist(fontName) {
// ...
}

if (!doesFontExists("Source Han Serif CN")) {
// 把 Typekit 提供的载入代码放在这里
}
</script>

doesFontExists 检测代码不依赖于任何库,因此可以放在非常开始的地方执行,从而可以快速载入字体。有一点需要注意的是 doesFontExists 的参数。同为思源宋体,Typekit 在线字体的名称和本地安装的版本可能是不同的。这里我尚未作全面的检测。