【问题标题】:How to detect if CSS @font-face is NOT used on a page?如何检测页面上是否未使用 CSS @font-face?
【发布时间】:2019-10-12 10:54:51
【问题描述】:

出于基于 Javascript 的自动未使用 CSS 删除的目的,我们正在寻找一种解决方案来检测页面上是否使用了 @font-face 块。

有没有一种简单的方法来验证字体是否在 HTML 中使用?

getComputedStyle() 方法需要测试每个单独的 HTML 元素并且效率不高。

<style>@font-face {
  font-family: "Open Sans";
  src: url("/fonts/OpenSans-Regular-webfont.woff2") format("woff2"),
       url("/fonts/OpenSans-Regular-webfont.woff") format("woff");
}</style>
<html> ... </html>
<script>function test_if_open_sans_is_used() { return; }</script>

【问题讨论】:

    标签: javascript css dom fonts font-face


    【解决方案1】:

    document.fonts.check API 可用于检测字体使用情况。这取决于字体字符串style weight size font-family

    匹配 Open-Sans-Italic:

    document.fonts.check('italic 14px "Open Sans"');
    

    【讨论】:

      【解决方案2】:

      这将有助于确定给定网页上使用的所有字体。然后,您可以使用它来确定您的目标字体是否已被使用。

      const fontUnstack = (stack, size, style, weight) => {
          if (typeof stack === "string")
              stack = stack.match(/[^'",;\s][^'",;]*/g) || [];
      
          for (const family of stack) {
              if (document.fonts.check(style + ' ' + weight + ' ' + size + ' ' + family))
                  return family;
          }
          console.log('undetected font', fontStyle, fontWeight, fontSize, fontFamily, el);
          return null;
      };
      
      const els = document.querySelectorAll('*');
      let fonts = {};
      
      for (const el of els) {
          const computedStyles = [
              window.getComputedStyle(el),
              window.getComputedStyle(el, '::before'),
              window.getComputedStyle(el, '::after')
          ];
          for (const computedStyle of computedStyles) {
              const fontFamily = computedStyle.getPropertyValue('font-family'),
                    fontSize = computedStyle.getPropertyValue('font-size'),
                    fontStyle = computedStyle.getPropertyValue('font-style'),
                    fontWeight = computedStyle.getPropertyValue('font-weight'),
                    usedFontFamily = fontUnstack(fontFamily, fontSize, fontStyle, fontWeight);
      
              if (usedFontFamily && !fonts.hasOwnProperty(usedFontFamily))
                  fonts[usedFontFamily] = [];
              if (fonts[usedFontFamily].indexOf(fontStyle + ', ' + fontWeight) === -1)
                  fonts[usedFontFamily].push(fontStyle + ', ' + fontWeight);
          }
      }
      
      console.log(fonts);
      

      【讨论】:

      • 感谢您的建议!一些注意事项:1)它似乎不可靠(它测试 宽度变化以检测是否使用了字体,某些字体可能与基线字体具有相同的宽度)2)它不发现整个 HTML 文档(即视口)范围之外的“未使用”字体:它将触发@font-face 的字体下载 3) 它很慢:它需要测试每个单独的 HTML 元素你为什么不使用document.fonts.check 而不是 方法?
      • 感谢@optimalisatie 的输入。所以我确实编辑了我的回复以反映 document.fonts.check。出于兼容性原因,我最初没有使用它,但它似乎在我能够测试的浏览器中工作。话虽如此,此代码旨在供开发人员在浏览器的开发人员面板中使用,以确定给定页面中使用的字体。不打算在您的 JS 中使用,我想不出每次运行页面时都需要获取此信息的用例。
      【解决方案3】:

      没有可用于计算样式的 API 或 CSS 选择器。 (Old example with jQuery) 您唯一的选择是遍历整个 DOM,或者直接使用 Chrome css coverage

      如果您想自动化您的解决方案,您可以随时extend Chrome Dev tools

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2013-02-05
        • 2019-01-25
        • 2014-02-21
        • 2012-01-24
        • 2017-06-19
        • 1970-01-01
        • 2017-07-18
        • 1970-01-01
        相关资源
        最近更新 更多