Detect whether a particular font is installed
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.
精彩评论