如何在JavaScript中获取页面实际渲染的字体?
如何在Chrome DevTools中通过JavaScript获取实际渲染的字体?
当然有办法!而且完全可以在Chrome DevTools控制台里直接实现,不用依赖Puppeteer这类工具。下面给你两种可行的方案:
方案一:利用Chrome DevTools专属的actualFontFamily属性
Chrome在DevTools的上下文里,给getComputedStyle返回的样式对象添加了一个非标准的actualFontFamily属性——它直接返回元素实际渲染的字体名称,这应该是最直接高效的方法。
举个例子,假设你有一个元素:
<div id="test" style="font-family: Montserrat, Helvetica, sans-serif;">Hello World</div>
如果Montserrat字体没有加载或不存在,在DevTools控制台里执行以下代码:
const el = document.getElementById('test'); console.log(getComputedStyle(el).actualFontFamily); // 会输出 "Helvetica"(或者你的系统默认无衬线字体,取决于环境)
这个属性是Chrome DevTools特有的,普通网页的JavaScript无法访问,但在DevTools控制台里可以正常使用,完美匹配你“仅在DevTools中操作”的需求。
方案二:通过Canvas对比文本宽度(通用 fallback 方案)
如果出于某些原因actualFontFamily不可用,你可以用Canvas来检测不同字体渲染同一文本的宽度差异,从而推断实际使用的字体。原理是:不同字体渲染相同文本的宽度通常存在差异,我们可以逐个测试font-family列表里的字体,找到和实际渲染宽度一致的那个。
代码示例:
function getActualFontFamily(element) { const computedStyle = getComputedStyle(element); // 解析font-family列表,去掉引号和多余空格 const fontFamilyList = computedStyle.fontFamily.split(',') .map(font => font.trim().replace(/['"]/g, '')); // 用包含大小写字母的文本测试,减少宽度巧合的概率 const testText = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz'; const canvas = document.createElement('canvas'); const ctx = canvas.getContext('2d'); // 获取元素实际渲染文本的宽度 ctx.font = `${computedStyle.fontSize} ${computedStyle.fontFamily}`; const actualWidth = ctx.measureText(testText).width; // 逐个测试字体列表里的字体 for (const font of fontFamilyList) { ctx.font = `${computedStyle.fontSize} ${font}`; const testWidth = ctx.measureText(testText).width; // 宽度误差在0.1px以内就认为是实际使用的字体 if (Math.abs(testWidth - actualWidth) < 0.1) { return font; } } // 如果都匹配不上,返回列表最后一个备选字体 return fontFamilyList.pop(); } // 使用示例 const el = document.getElementById('test'); console.log(getActualFontFamily(el));
这个方法的优点是兼容性更好(甚至可以在普通网页JS里使用),缺点是需要处理字体宽度可能的微小差异,对于一些宽度接近的字体可能会有误差,但在大多数场景下足够可靠。
内容的提问来源于stack exchange,提问作者Misha Moroshko
相关产品推荐
相关产品推荐

