html 如何在JavaScript中获得渲染字体?

yhived7q  于 2023-01-28  发布在  Java
关注(0)|答案(2)|浏览(250)

Google Chrome在DevTools中显示渲染字体。
例如,给定:

font-family: Montserrat, Helvetica, sans-serif;

并且Montserrat字体丢失/被禁用,Chrome告诉我们Helvetica正在被渲染:

有没有办法在JavaScript中获得渲染字体?(即使它只在Chrome中工作)

    • 注:**
  1. This solution建议使用getComputedStyle(...).fontFamily,但它返回CSS声明"Montserrat, Helvetica, sans-serif",而不是实际呈现的字体。
  2. This solution使用puppeteer,但我不知道如何在DevTools中实现相同的功能(没有puppeteer)。
nhn9ugyo

nhn9ugyo1#

仍然无法从Web-API访问此信息。
胡迪尼小组正在讨论包括font-metrics API,这是应该包括这样的东西,但它甚至还没有提出作为一个规范草案,将有很多的道路上的负担。
使用的是什么字体?这很复杂,因为每个段落,每行,每个单词,甚至每个字形都可以使用多种字体。字体应该以句柄的形式显示,包含完整的字体信息,以及(对于Web字体)原始字体数据的句柄。dbaron & eae将拥有这一领域,并提出一个API。
实际上,可以具有用于字形̂(U+0302)的一种字体,以及用于字形a(U+0061)的另一种字体,这将使得组合的字形实际上使用两种不同的字体。
当前的讨论似乎指向document.measureElementdocument.measureText方法提供的Font接口。一个DOMString name和一个数字glyphsRendered。然而,再一次,这些仍然是讨论,仍然没有作为草案提出,仍然有很多讨论要做,我不会屏住呼吸等待它很快在任何地方实现。
现在,有一些黑客,比如numerous other Q/A already told,不要坚持接受那里的答案,这意味着最简单的要看渲染的大小,更高级的要看渲染的像素,但是作为黑客,他们不会在每种情况下都有效。
例如,我可以在我的系统上有一个自定义字体,它只会呈现从一个众所周知的字体借用的一些字符,没有这样的黑客能够告诉浏览器是否后退到那个字体或实际的众所周知的字体。
唯一确定的方法是保留控件并使用Web字体。

ibrsph3r

ibrsph3r2#

由于还没有人提出过这个建议,因此还有一种方法可以找出呈现的是哪种字体。
下面的代码片段获取元素使用的字体系列CSS定义(当然,如果需要,您也可以硬编码字体系列名称),并按顺序检查字体系列是否已加载,然后返回第一个加载的字体系列的名称。
由于font-family CSS属性指定了一个或多个字体系列名称的优先级列表,因此第一个可用字体很可能也是呈现的字体。Snippet使用CSS字体加载API,该API得到了很好的支持(当然IE中没有)https://developer.mozilla.org/en-US/docs/Web/API/CSS_Font_Loading_API
例如,让我们想象CSS将是:

.body { 
    font-family: -apple-system, BlinkMacSystemFont, "Segoe UI Adjusted", "Segoe UI", "Liberation Sans", sans-serif;
}

片段

const getRenderedFontFamilyName = ( element ) => {
    // Font families set in CSS for the element
    const fontFamilies = window.getComputedStyle( element, null ).getPropertyValue( "font-family" );
    // const hardcodedFamilies = '-apple-system, BlinkMacSystemFont, "Segoe UI Adjusted", "Segoe UI", "Liberation Sans", sans-serif';
    
    // Remove the " sign from names (font families with spaces in their names) and split names to the array
    const fontFamiliesArr = fontFamilies.replaceAll('"', "").split(", ");

    // Find the first loaded font from the array
    return fontFamiliesArr.find( e => document.fonts.check( `12px ${e}`) );
}

示例如何获取StackOverflow主体的渲染字体系列:

getRenderedFontFamilyName(document.querySelector('body'));

相关问题