【问题标题】:How to detect which one of the defined font was used in a web page?如何检测网页中使用了哪一种定义的字体?
【发布时间】:2010-09-05 06:38:37
【问题描述】:

假设我的页面中有以下 CSS 规则:

body {
    font-family: Calibri, Trebuchet MS, Helvetica, sans-serif;
}

如何检测用户浏览器中使用了哪一种定义的字体?

对于想知道我为什么要这样做的人来说,因为我检测到的字体包含其他字体中可用的字形。如果用户确实没有有字体,那么我希望它显示一个链接,要求用户下载该字体(这样他们就可以使用我的网络应用程序和正确的字体)。

目前,我正在为所有用户显示下载字体链接。我只想为那些没有安装了正确字体的人显示这个。

【问题讨论】:

  • 要记住的一点是,某些浏览器会用相似的字体替换某些丢失的字体,这是无法使用 JavaScript/CSS 技巧检测到的。例如,如果没有安装 Helvetica,Windows 浏览器会用 Arial 代替它。 MojoFilter 和 dragonmatank 提到的技巧仍然会报告 Helvetica 已安装,即使它没有安装。
  • 小提示:如果您提供下载 Calibri 的链接,请注意虽然它捆绑在多个 Microsoft 产品中,但它不是免费字体,并且您通过提供下载来侵犯版权。
  • 这几天你也可以使用FontFaceSet接口来检查字体是否可用;见developer.mozilla.org/en-US/docs/Web/API/FontFaceSet/check
  • 实际上,您无法检查 div 使用了哪种字体,因为任何单个缺失的字符都可能从另一种字体中窃取。

标签: javascript html css fonts


【解决方案1】:

我已经看到它以一种不确定但非常可靠的方式完成。基本上,一个元素被设置为使用特定的字体,并且一个字符串被设置为该元素。如果为元素设置的字体不存在,则采用父元素的字体。所以,他们所做的是测量渲染字符串的宽度。如果它与他们对所需字体的期望相匹配,而不是派生字体,那么它就存在。这不适用于等宽字体。

这就是它的来源: Javascript/CSS Font Detector (ajaxian.com; 12 Mar 2007)

【讨论】:

  • canvas 元素中使用measureText 的另一种方法:github.com/Wildhoney/DetectFont
  • 链接可能已损坏,他们将我重定向到广告。只有我吗?
  • 是的,它已经消失了。我想这对于一篇 15 岁的文章来说应该不足为奇。 @Wildhoney 使用的方法听起来非常相似。
【解决方案2】:

我编写了一个简单的 JavaScript 工具,您可以使用它来检查是否安装了字体。
它使用简单的技术,并且在大多数情况下应该是正确的。

jFont Checker 在 github

【讨论】:

  • 字体检测不能解决问题。您可以使用它来迭代认为声明的字体并检查什么是有效的,但它很少或根本没有关于任何给定 div 使用什么字体的信息。如果你从JS创建div,我们怎么知道使用的是什么字体?
  • @JonLennartAasenden 要获得使用的字体,我相信您可以使用“computedStyle”属性(我忘记了确切的名称,但它是这样的。)
  • 我写了一个适用于所有浏览器的类。它是用 Smart Pascal 编写的,可以编译为 JS,所以我不能在这里真正发布解决方案 - 但简而言之,我必须提取 font-family 字符串,然后检查每种字体是否有效,获取第一个有效的字体 - 然后无处不在。我将“字体检测器”移植到 smart pascal 并进行了一些调整。
  • @JonLennartAasenden 这听起来不像你的课是万无一失的。浏览器会按给定的优先级检查每种字体(如果已安装),但有时会选择使用列表中优先级较低的字体,如果优先级较高的已安装字体缺少字符或字形与请求的大小不匹配。
【解决方案3】:

@pat 实际上,Safari 并没有给出使用的字体,而是无论是否安装,Safari 总是返回堆栈中的第一个字体,至少在我的经验中是这样。

font-family: "my fake font", helvetica, san-serif;

假设 Helvetica 是已安装/使用的,您将获得:

  • Safari 中的“my fake font”(我相信其他 webkit 浏览器)。
  • Gecko 浏览器和 IE 中的“my fake font, helvetica, san-serif”。
  • Opera 9 中的“helvetica”,尽管我读到他们正在 Opera 10 中更改它以匹配 壁虎。

我通过了这个问题并创建了Font Unstack,它测试堆栈中的每种字体并仅返回第一个安装的字体。它使用@MojoFilter 提到的技巧,但如果安装了多个,则仅返回第一个。尽管它确实存在@tlrobinson 提到的弱点(Windows 会默默地用 Arial 替换 Helvetica 并报告 Helvetica 已安装),但它在其他方面运行良好。

【讨论】:

    【解决方案4】:

    一种有效的技术是查看元素的计算样式。这在 Opera 和 Firefox 中受支持(我在 safari 中进行了侦察,但尚未测试)。 IE(至少 7 个)提供了一种获取样式的方法,但它似乎是样式表中的任何内容,而不是计算样式。更多关于 quirksmode 的详细信息:Get Styles

    这是一个获取元素中使用的字体的简单函数:

    /**
     * Get the font used for a given element
     * @argument {HTMLElement} the element to check font for
     * @returns {string} The name of the used font or null if font could not be detected
     */
    function getFontForElement(ele) {
        if (ele.currentStyle) { // sort of, but not really, works in IE
            return ele.currentStyle["fontFamily"];
        } else if (document.defaultView) { // works in Opera and FF
            return document.defaultView.getComputedStyle(ele,null).getPropertyValue("font-family");
        } else {
            return null;
        }
    }
    

    如果用于此的 CSS 规则是:

    #fonttester {
        font-family: sans-serif, arial, helvetica;
    }
    

    如果安装了 helvetica,则返回 arial,最后返回系统默认无衬线字体的名称。请注意,CSS 声明中的字体顺序很重要。

    您还可以尝试一个有趣的技巧,即创建许多具有许多不同字体的隐藏元素,以尝试检测机器上安装了哪些字体。我相信有人可以用这种技术制作一个漂亮的字体统计收集页面。

    【讨论】:

    • 这将返回 CSS 的完整字符串,例如“Helvetica,Arial,sans-serif”。它不返回实际使用的字体。
    【解决方案5】:

    一个简化的形式是:

    function getFont() {
        return document.getElementById('header').style.font;
    }
    

    如果您需要更完整的内容,请查看this

    【讨论】:

      【解决方案6】:

      有一个简单的解决方案 - 只需使用element.style.font

      function getUserBrowsersFont() {
          var browserHeader = document.getElementById('header');
          return browserHeader.style.font;
      }
      

      此功能将完全满足您的需求。执行时它将返回用户/浏览器的字体类型。希望这会有所帮助。

      【讨论】:

      • 我在 Safari 中尝试这个肯定有 Arial 字体的元素,我得到 "" 作为字体。关于为什么的任何想法?
      • 最可能的原因是这只是检查设置的字体,如果没有设置字体,则可能是使用Arial作为字体。
      • @AlessandroVermeulen 这是因为 element.style 只返回样式属性中设置的值,而不会返回来自其他地方的任何值(即不会返回来自样式元素、外部 css 或用户代理默认值的值) .这个答案应该被删除,因为它具有误导性/不正确。难以置信,它得到了赏金!
      • 很抱歉,但我认为这不是正确的答案。虽然这会打印出该 CSS 属性的值,但它不会返回浏览器正在使用的实际 rendered 字体。
      【解决方案7】:

      另一种解决方案是通过@font-face 自动安装字体,这可能不需要检测。

      @font-face {
        font-family: "Calibri";
        src: url("http://www.yourwebsite.com/fonts/Calibri.eot");
        src: local("Calibri"), url("http://www.yourwebsite.com/fonts/Calibri.ttf") format("truetype");
      }
      

      当然它不会解决任何版权问题,但是您始终可以使用免费软件字体,甚至制作自己的字体。您将需要 .eot.ttf 文件才能发挥最佳效果。

      【讨论】:

        【解决方案8】:

        Calibri 是 Microsoft 拥有的字体,不应免费分发。此外,要求用户下载特定字体也不是很友好。

        我建议购买该字体的许可证并将其嵌入到您的应用程序中。

        【讨论】:

        • +1 用于字体嵌入。这解决了问题,而无需检测任何东西。
        • 我建议在购买任何东西之前检查Google Fonts是否有类似的东西。
        • 除了,如果用户在 Windows 机器上,他们可以查看 Calibri。这是后备列表的全部要点。
        • 而且你的回答与问题无关,应该是评论。
        【解决方案9】:

        我正在使用 Fount。您只需将 Fount 按钮拖到书签栏上,单击它,然后单击网站上的特定文本。然后它将显示该文本的字体。

        https://fount.artequalswork.com/

        【讨论】:

          【解决方案10】:

          您可以将Adobe Blank 放在您要查看的字体之后的字体系列中,然后不会呈现任何不在该字体中的字形。

          例如:

          font-family: Arial, 'Adobe Blank';
          

          据我所知,没有 JS 方法可以判断元素中的哪些字形是由该元素的字体堆栈中的哪种字体呈现的。

          这很复杂,因为浏览器有 serif/sans-serif/monospace 字体的用户设置,并且它们也有自己的硬编码后备字体,如果在任何字体堆栈中的字体。 因此浏览器可能会以不在字体堆栈或用户浏览器字体设置中的字体呈现某些字形。 Chrome Dev Tools will show you each rendered font for the glyphs in the selected element。所以在你的机器上你可以看到它在做什么,但是没有办法知道在用户的机器上发生了什么。

          用户的系统也可能在其中发挥作用,例如Window does Font Substitution 在字形级别。

          所以...

          对于您感兴趣的字形,您无法知道它们是否会被用户的浏览器/系统回退呈现,即使它们没有您指定的字体。

          如果您想在 JS 中对其进行测试,您可以使用包括 Adob​​e Blank 在内的字体系列渲染单个字形并测量它们的宽度以查看它是否为零,但是您必须彻底迭代每个字形和您要测试的每种字体,但是尽管您可以知道元素字体堆栈中的字体,但无法知道用户的浏览器配置为使用哪些字体,因此至少在某些情况下您的用户您遍历的字体列表将不完整。 (如果新字体出现并开始被使用,这也不是未来的证据。)

          【讨论】:

            【解决方案11】:

            你可以使用这个网站:

            http://website-font-analyzer.com/

            它正是你想要的......

            【讨论】:

            • @MehranTM 是的,这个项目几年前就终止了。
            猜你喜欢
            • 2018-10-23
            • 2017-11-15
            • 2012-07-24
            • 1970-01-01
            • 1970-01-01
            • 2022-01-15
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多