开发者

Detect whether a particular font is installed

开发者 https://www.devze.com 2022-12-31 09:56 出处:网络
How to detect whether or not a particular font is installed using javascript only. (Disregard to whether it is enabled or not).

How to detect whether or not a particular font is installed using javascript only. (Disregard to whether it is enabled or not).

Than开发者_运维知识库ks


The last answer was provided 11 years ago. In the meantime there are new solutions available for people who are still looking for a solution:

You could use the FontFaceSet API provided by browsers. It is currently still an experimental technology, but already available in most browsers (except IE).

From MDN Web Docs

The check() method of the FontFaceSet returns whether all fonts in the given font list have been loaded and are available.

Example:

const fontAvailable = document.fonts.check("16px Arial");

When using the check() method, make sure to check if font loading operations have been completed by using the ready property, which returns a Promise when the loading has finished:

let fontAvailable;
document.fonts.ready.then(() => {
    fontAvailable = document.fonts.check("16px Arial");
});


Here is a solution to check if font is installed in your device in a html page. The idea is :create a extreme narrow font and define it in css with data object url, check target font's width with this font.

Here is the example:

<!DOCTYPE html>
<html lang="en" xmlns="http://www.w3.org/1999/xhtml">
<head>
    <meta charset="utf-8" />
    <title></title>
    <script type="text/javascript">
        (function () {
            const context = document.createElement("canvas").getContext("2d");
            context.font = "200px SANS-SERIF"
            const TEXT_TO_MEASURE = "A";
            var FONT_WIDTH = context.measureText(TEXT_TO_MEASURE).width;
            (function () {
                var style = document.createElement("style");
                style.setAttribute("type", "text/css");
                style.textContent = `@font-face{font-family:'__DEFAULT_FONT__';src:url('data:application/font-woff;base64,d09GRgABAAAAAAM0AAsAAAAABCQAAQAAAAAAAAAAAAAAAAAAAAAAAAAAABVPUy8yAAABcAAAADwAAABgNVxaOmNtYXAAAAG0AAAAKQAAADQADACUZ2FzcAAAAywAAAAIAAAACP//AANnbHlmAAAB6AAAACQAAAAwK9MKuGhlYWQAAAEIAAAAMwAAADYLo1XbaGhlYQAAATwAAAAcAAAAJP2RAdRobXR4AAABrAAAAAgAAAAIAMn9LGxvY2EAAAHgAAAABgAAAAYAGAAMbWF4cAAAAVgAAAAXAAAAIAAEAAVuYW1lAAACDAAAAQsAAAHwJKxCKHBvc3QAAAMYAAAAEwAAACD/KgCWeNpjYGRgYABi+QdqV+P5bb4ycHMwgMD1GraPEJqz/d80BoZ/PxgygFw2kFoGBgA++AvVAHjaY2BkYGBgBMOUf9MYc/79YACJIAMmAF7xBGN42mNgZGBgYGJgYQDRDFASCQAAAQEACgB42mNgZkhhnMDAysDAOovVmIGBURpCM19kSGMSYmBgAklhBR4+CgoMDgyOQMgIhhlgYUYoCaEZAIdLBiEAZP6WAGT+lnjaY2BgYGJgYGAGYhEgyQimWRgUgDQLEIL4jv//Q8j/B8B8BgBSlwadAAAAAAAADAAYAAB42mNg/DeNgeHfD4YMBmYGBkVTY9F/05IyMhgYcIgDAGnPDrV42oWQzU7CUBCFvwISZcEz3LjSBBoQ/yIrYzTEGEmIYY9QiglS01YMOx/DV+AtPXeophtjmumdOffMmXMH2GdOlaB2ACwUuzwQvi7yCk3d7PIqh794rcTZI+WryOslvMFn0OCJDW9EmjRhqtOxVRwJTXhXpxOa8CrOhJXQY0JhJ3Tocmn5NUt9jhEvxHKTk1kV6YyksNZ/ZnUsxaV0Uh4ZKm65YmycTL2J9J1UQ2l3/sT73JvKxlz0aJXc9Lkzds6NeiNNylWn1u37z0wjFP9UcSH8XFmbZ03JtYmFTu99Xqg4PqSR2Q5+9PxbnBx4Zyu9yP070+ultkPHoNhRmwchsaqpOLbhb0h9RfYAeNpjYGYAg//qDNMYsAAAKDQBwAAAAAAB//8AAg==');}`;
                document.documentElement.appendChild(style);
                var handleId = null;
                (function initailizeDefaultFont() {
                    context.font = "200px __DEFAULT_FONT__";
                    var width = context.measureText(TEXT_TO_MEASURE).width;
                    if (width != FONT_WIDTH) {
                        FONT_WIDTH = width;
                        cancelAnimationFrame(handleId);
                    }
                    else if (handleId == null) {
                        handleId = requestAnimationFrame(initailizeDefaultFont);
                    }

                })();
            })();
            function checkFontAvailable(font) {
                if (/^\s*SANS-SERIF\s*$/i.test(font)) {
                    return true;
                }
                if (!font || font == '__DEFAULT_FONT__') {
                    return false;
                }

                context.font = `200px ${font.replace(/^\s*['"]|['"]\s*$/g, "")}, __DEFAULT_FONT__`;

                var width = context.measureText(TEXT_TO_MEASURE).width;

                return width != FONT_WIDTH;
            }
            this.checkFontAvailable = checkFontAvailable;
        }).apply(this);

        console.log([checkFontAvailable("arial black b"), checkFontAvailable("arial black")]);
    </script>
</head>
<body>

</body>
</html>

Here is the test result:

checkFontAvailable("微软雅黑333")
false
checkFontAvailable("微软雅黑")
true
checkFontAvailable("arial")
true
checkFontAvailable("arial black")
true


Put this code anywhere in your javascript file.

(function (document) {
    var width;
    var body = document.body;
  
    var container = document.createElement('span');
    container.innerHTML = Array(100).join('wi');
    container.style.cssText = [
      'position:absolute',
      'width:auto',
      'font-size:128px',
      'left:-99999px'
    ].join(' !important;');
  
    var getWidth = function (fontFamily) {
      container.style.fontFamily = fontFamily;
  
      body.appendChild(container);
      width = container.clientWidth;
      body.removeChild(container);
  
      return width;
    };
  
    // Pre compute the widths of monospace, serif & sans-serif
    // to improve performance.
    var monoWidth  = getWidth('monospace');
    var serifWidth = getWidth('serif');
    var sansWidth  = getWidth('sans-serif');
  
    window.isFontAvailable = function (font) {
      return monoWidth !== getWidth(font + ',monospace') ||
        sansWidth !== getWidth(font + ',sans-serif') ||
        serifWidth !== getWidth(font + ',serif');
    };
  })(document);

Usage

console.log(isFontAvailable('Arial Black'))
// Evaluates true
console.log(isFontAvailable('thisdoesntexists'))
// Evaluates false

Source

https://www.samclarke.com/javascript-is-font-available


If you absolutely need a specific font, all your visitors must have current browsers. Then you can use webfonts.

If that's not an option, you must render the font on your server and serve an image.


@Matchu suggested you rightly but here is what you are looking for:

http://remysharp.com/2008/07/08/how-to-detect-if-a-font-is-installed-only-using-javascript/


Font family declarations should suffice to provide a fallback in case the font you want to use is not present.

But if you really need to use a special font in your site, although this uses JavaScript, I'd recommend Cufon since it's the most cross-browser solution out there - there is a CSS3 fix (font-face declarations), but it doesn't work in all browsers yet.


How about you just do what the rest of the world does: specify the font with CSS, and offer fallbacks? No app should ever need to know what fonts are available, nor is there a reliable way of doing so. (You would probably have to print hidden div with the font and measure it to see if the dimensions are what you expected, but that would be extremely brittle.)

Just go for:

body { font-family: MyFont, Helvetica, Arial, sans-serif }

If you want to be doing anything with the font other than display things in it if possible, consider an alternative solution.

0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号