如何获取元素渲染字体的文件名?(用于Vitest字体测试)
获取页面元素渲染字体的文件名方法
浏览器没有直接提供API返回元素使用的字体文件路径,但可以通过解析CSS规则或利用FontFace API实现,以下是针对你的Vitest测试场景的具体方案:
方法一:解析@font-face规则匹配对应字体路径
实现步骤:
- 获取目标元素的计算样式(font-family、font-weight、font-style)
- 遍历页面所有样式表,收集所有@font-face规则并提取关键信息
- 匹配元素样式与@font-face规则,提取对应的字体文件路径
测试代码示例:
import { render, screen, waitFor } from '@testing-library/react'; import YourComponent from './YourComponent'; test('验证元素使用指定字体文件', async () => { render(<YourComponent />); const targetElement = screen.getByClassName('my-font-bold'); // 等待样式加载完成 await waitFor(() => window.getComputedStyle(targetElement).fontFamily); // 获取元素计算样式 const computedStyle = window.getComputedStyle(targetElement); const fontFamily = computedStyle.fontFamily.replace(/['"]/g, ''); const fontWeight = computedStyle.fontWeight; const fontStyle = computedStyle.fontStyle; // 收集所有@font-face规则 const fontFaceRules = Array.from(document.styleSheets) .flatMap(sheet => { // 处理跨域样式表无法访问的情况 try { return Array.from(sheet.cssRules); } catch (e) { return []; } }) .filter(rule => rule.type === CSSRule.FONT_FACE_RULE) .map(rule => ({ fontFamily: rule.style.fontFamily.replace(/['"]/g, ''), fontWeight: rule.style.fontWeight, fontStyle: rule.style.fontStyle, src: rule.style.src })); // 匹配对应规则 const matchedRule = fontFaceRules.find(rule => rule.fontFamily === fontFamily && rule.fontWeight === fontWeight && rule.fontStyle === fontStyle ); expect(matchedRule).not.toBeNull(); if (matchedRule) { // 提取字体文件路径 const urlMatch = matchedRule.src.match(/url\(['"]?([^'")]+)['"]?\)/); expect(urlMatch).not.toBeNull(); expect(urlMatch[1]).toBe('../../public/fonts/MyFont-Bold.woff2'); } });
方法二:利用FontFace API(局限性:仅能获取已加载的字体)
如果字体已成功加载,可以通过document.fonts获取FontFace对象,但需注意其src属性可能返回解析后的绝对路径,而非原始相对路径:
test('验证已加载字体的路径', async () => { render(<YourComponent />); await document.fonts.ready; // 等待所有字体加载完成 const targetElement = screen.getByClassName('my-font-bold'); const computedStyle = window.getComputedStyle(targetElement); const fontFamily = computedStyle.fontFamily.replace(/['"]/g, ''); const fontWeight = computedStyle.fontWeight; const fontStyle = computedStyle.fontStyle; const matchedFont = Array.from(document.fonts).find(font => font.family.replace(/['"]/g, '') === fontFamily && font.weight === fontWeight && font.style === fontStyle ); expect(matchedFont).not.toBeNull(); // 这里的src可能是绝对路径,需根据实际测试环境调整断言 expect(matchedFont.src).toContain('MyFont-Bold.woff2'); });
注意事项:
- 若样式表为跨域资源,浏览器会限制访问
cssRules,需确保样式表同域或配置CORS - 测试时需等待样式和字体加载完成,可使用
waitFor或document.fonts.ready - 方法一的兼容性更好,不受字体是否加载完成的影响
内容的提问来源于stack exchange,提问作者Theo Cerutti
相关产品推荐
相关产品推荐

