起因是最近项目要用的这种选字体的需求,所以就调研了一下实现方法,然后就有了这篇笔记
1.Chrome实验性接口 queryLocalFonts
Chrome 从v103开始支持该接口,是异步接口,返回Promise对象
js
if ('queryLocalFonts' in window) {
queryLocalFonts().then(fonts => console.log(fonts))
}
如果是第一次使用,会弹出提示,点同意后返回本地的字体数组
如果浏览器不支持该接口,或是弹窗点了拒绝,则queryLocalFonts
为undefined
2. document.fonts
document.fonts 接口是 CSS 字体加载 API 的一部分,用于管理和加载浏览器中的字体
目前除了IE,流行浏览器都支持,但是该接口只能检查某字体是否可用,而无法给出系统支持的字体清单
所以事先需要有一份检测的字体清单,来检查哪些字体可使用
js
if (document.fonts.check('12px 宋体')) {
console.log('字体可用');
} else {
console.log('字体不可用');
}
此外还有load
方法
js
document.fonts.load('9px Arial').then(() => {
console.log('font loaded')
}, () => {
console.log('error')
})
注意传参是CSS语法,所以9px Arial
需带上9px
,当然9rem
之类也是可以的
3. 利用Canvas
可以用待检测的字体在Canvas写字,再获取宽度,跟用系统默认字体渲染的对比,如果不一样,则是渲染字体成功,如果缺字体,会用默认字体替换,这样渲染出来的宽度就没变化,则可以判断为无该字体
js
function detectFont(font) {
const canvas = document.createElement('canvas')
const context = canvas.getContext('2d')
const text = 'abcdefghijklmnopqrstuvwxyz0123456789'
context.font = '72px Segoe UI'
let baseSize = context.measureText(text).width
context.font = '72px ' + font + ', Segoe UI'
let newSize = context.measureText(text).width
return newSize !== baseSize
}
detectFont('宋体')
// true
detectFont('仿宋')
// true
detectFont('PingFang SC')
// false
值得一提的是这个办法并非100%准确,例如不同浏览器渲染的差异、浏览器对缺失字体的处理方式、以及不同字体的宽度有可能一致等诸多原因。
综上所述,不同的方法各有优劣,开发者应结合项目需求选择合适的方式进行字体检测。通过灵活运用 以上方法,能够在大多数场景下满足字体检测的需求。这篇笔记希望能为你在实际开发中提供帮助,也希望能够提升你项目的用户体验和设计一致性。