Skip to content

Instantly share code, notes, and snippets.

@alex-kinokon
Last active August 29, 2015 14:26
Show Gist options
  • Save alex-kinokon/539cc8969ed7a56a42f0 to your computer and use it in GitHub Desktop.
Save alex-kinokon/539cc8969ed7a56a42f0 to your computer and use it in GitHub Desktop.
// hasFont.js
// Detects whether a font exists on a client with pure JavaScript.
// Released under CC0 1.0 Public Domain Dedication
// https://creativecommons.org/publicdomain/zero/1.0/
// Boolean hasFont(String fontName)
// n.b. fontName should not have double quotation marks, i.e. `"`
// e.g. hasFont('monospace') // true
// hasFont('Helvetica Nonexistent') // false
var hasFont = (function(doc){
// Internet Explorer 8: Array.prototype.every polyfill
// If you don't need to support IE8 or lower, suppress this line.
Array.prototype.every||(Array.prototype.every=function(r,t){"use strict";var e,n;if(null==this)throw new TypeError;var o=Object(this),i=o.length>>>0;if("function"!=typeof r)throw new TypeError;for(arguments.length>1&&(e=t),n=0;i>n;){var f;if(n in o){f=o[n];var y=r.call(e,f,n,o);if(!y)return!1}n++}return!0});
var standard = doc.createElement('span');
var experiment = doc.createElement('span');
var checksAgainst = ["monospace", "Georgia", "Times New Roman", "Verdana"];
var alphabet = "ABCDEFGHIJKLMNOPQRSTUVWXYZ".split('');
var style = 'opacity: 0; font-size: 99px; position: absolute; top: -19999px; left: -1999px; margin: 0';
standard.setAttribute('style', style);
experiment.setAttribute('style', style);
var identical = function (standard, experiment) {
return ((standard.offsetHeight === experiment.offsetHeight) &&
(standard.offsetWidth === experiment.offsetWidth));
};
var check = function (fontName) {
return !checksAgainst.every(function(fallback) {
standard.style.fontFamily = fallback;
experiment.style.fontFamily = fontName.trim() + ', ' + fallback;
return alphabet.every(function(letter){
standard.innerText = experiment.innerText = Array(70).join(letter);
return identical(standard, experiment);
});
});
};
return function (fontName) {
doc.body.appendChild(standard);
doc.body.appendChild(experiment);
var result = check('"' + fontName + '"');
doc.body.removeChild(standard);
doc.body.removeChild(experiment);
return result;
};
})(document);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment