列出用户的浏览器可以显示的每种字体

有没有在JavaScript的方式来获得浏览器可以显示的所有字体(或字体家族)的名称? (我想为用户提供一个包含所有可用字体列表的下拉列表,并允许用户select一种字体。)我宁愿不必提前对列表进行硬编码,也不要将其从服务器上发送出去。 (直觉上,浏览器似乎应该知道它有什么样的字体,而且应该以某种方式暴露给javascript。)

JavaScript版本有点片面。 它通过迭代已知的字体和testing来获取字体。

最准确的方法(尽pipe不得不使用合适的插件)是使用Flash 。 在这里,您可以获取字体列表,而不必单独使用尺寸对它们进行testing。

你将不得不决定是否有一个确切的清单,而不是在一些设备上工作(iDevices,浏览器没有Flash插件等),或部分列表更好的支持通过JavaScript只 。

就在这里! 我很高兴你问这个问题,因为我现在也想用这个。

+1的问题,这里是你的答案:)

http://www.lalit.org/lab/javascript-css-font-detect

来自wordpress/wp-content/uploads/2008/05/fontdetect.js; 代码

/** * JavaScript code to detect available availability of a * particular font in a browser using JavaScript and CSS. * * Author : Lalit Patel * Website: http://www.lalit.org/lab/javascript-css-font-detect/ * License: Apache Software License 2.0 * http://www.apache.org/licenses/LICENSE-2.0 * Version: 0.15 (21 Sep 2009) * Changed comparision font to default from sans-default-default, * as in FF3.0 font of child element didn't fallback * to parent element if the font is missing. * Version: 0.2 (04 Mar 2012) * Comparing font against all the 3 generic font families ie, * 'monospace', 'sans-serif' and 'sans'. If it doesn't match all 3 * then that font is 100% not available in the system * Version: 0.3 (24 Mar 2012) * Replaced sans with serif in the list of baseFonts */ /** * Usage: d = new Detector(); * d.detect('font name'); */ var Detector = function() { // a font will be compared against all the three default fonts. // and if it doesn't match all 3 then that font is not available. var baseFonts = ['monospace', 'sans-serif', 'serif']; //we use m or w because these two characters take up the maximum width. // And we use a LLi so that the same matching fonts can get separated var testString = "mmmmmmmmmmlli"; //we test using 72px font size, we may use any size. I guess larger the better. var testSize = '72px'; var h = document.getElementsByTagName("body")[0]; // create a SPAN in the document to get the width of the text we use to test var s = document.createElement("span"); s.style.fontSize = testSize; s.innerHTML = testString; var defaultWidth = {}; var defaultHeight = {}; for (var index in baseFonts) { //get the default width for the three base fonts s.style.fontFamily = baseFonts[index]; h.appendChild(s); defaultWidth[baseFonts[index]] = s.offsetWidth; //width for the default font defaultHeight[baseFonts[index]] = s.offsetHeight; //height for the defualt font h.removeChild(s); } function detect(font) { var detected = false; for (var index in baseFonts) { s.style.fontFamily = font + ',' + baseFonts[index]; // name of the font along with the base font for fallback. h.appendChild(s); var matched = (s.offsetWidth != defaultWidth[baseFonts[index]] || s.offsetHeight != defaultHeight[baseFonts[index]]); h.removeChild(s); detected = detected || matched; } return detected; } this.detect = detect; }; 

概要

它是如何工作的?

此代码的工作原理是每个字符在不同的字体中显示不同。 所以不同的字体对于相同字体大小的同一个string将采用不同的宽度和高度。

 <SCRIPT> function getFonts() { var nFontLen = dlgHelper.fonts.count; var rgFonts = new Array(); for ( var i = 1; i < nFontLen + 1; i++ ) rgFonts[i] = dlgHelper.fonts(i); rgFonts.sort(); for ( var j = 0; j < nFontLen; j++ ) document.write( rgFonts[j] + "<BR>" ); } </SCRIPT> <BODY onload="getFonts()"> <OBJECT id=dlgHelper CLASSID="clsid:3050f819-98b5-11cf-bb82-00aa00bdce0b" width="0px" height="0px"> </OBJECT> 

在我的search中,我还find了Font.js ,它像Image一样添加了一个Font对象,所以可以检查字体是否准备好使用。 也适用于已安装/系统字体。 由于需要Object.defineProperty (其他浏览器都有),所以只能使用IE9 +,但是如果你使用的是现代networking,这看起来更好。 (不幸的是,我将不得不采取上述的答案,现在就开始行动起来吧:))

也许这可以用完全不同的方式完成,使用具有已知字体图像的spritesheet作为特定字符,并将其与用相同字符绘制的canvas元素的快照进行比较,以及浏览器报告为相同字体。 比较可以用像like.js这样的东西来完成。

这是慢的,但也应该让我们检测浏览器是在撒谎。

我给Lalit Patel的Detector上面添加了两个方法:

  • addFont(family,stylesheetUrl,ruleString) – >检测字体'family'是否存在,如果没有添加stylesheetUrl加载字体(如果给定的话),否则ruleString
  • addFontsArr(arr) – >添加一个字体数组

有了这个你可以这样做:

 fonts = [ 'Arial', 'Arial Black', { family: 'Lato', stylesheetUrl: 'https://fonts.googleapis.com/css?family=Lato'}, 'Leelawadee UI'] (new FontDetector()).addFontsArr(fonts); 

码:

 /** * JavaScript code to detect available availability of a * particular font in a browser using JavaScript and CSS. * * Author : Lalit Patel * Website: http://www.lalit.org/lab/javascript-css-font-detect/ * License: Apache Software License 2.0 * http://www.apache.org/licenses/LICENSE-2.0 * Version: 0.15 (21 Sep 2009) * Changed comparision font to default from sans-default-default, * as in FF3.0 font of child element didn't fallback * to parent element if the font is missing. * Version: 0.2 (04 Mar 2012) * Comparing font against all the 3 generic font families ie, * 'monospace', 'sans-serif' and 'sans'. If it doesn't match all 3 * then that font is 100% not available in the system * Version: 0.3 (24 Mar 2012) * Replaced sans with serif in the list of baseFonts */ /** * Usage: d = new Detector(); * d.detect('font name'); */ function FontDetector() { this.detect = detect; this.addFont = addFont; this.addFontsArr = addFontsArr; // a font will be compared against all the three default fonts. // and if it doesn't match all 3 then that font is not available. var baseFonts = ['monospace', 'sans-serif', 'serif']; //we use m or w because these two characters take up the maximum width. // And we use a LLi so that the same matching fonts can get separated var testString = "mmmmmmmmmmlli"; //we test using 72px font size, we may use any size. I guess larger the better. var testSize = '72px'; var h = document.getElementsByTagName("body")[0]; // create a SPAN in the document to get the width of the text we use to test var s = document.createElement("span"); s.style.fontSize = testSize; s.innerHTML = testString; var defaultWidth = {}; var defaultHeight = {}; for (var index in baseFonts) { //get the default width for the three base fonts s.style.fontFamily = baseFonts[index]; h.appendChild(s); defaultWidth[baseFonts[index]] = s.offsetWidth; //width for the default font defaultHeight[baseFonts[index]] = s.offsetHeight; //height for the defualt font h.removeChild(s); } function detect(font) { var detected = false; for (var index in baseFonts) { s.style.fontFamily = font + ',' + baseFonts[index]; // name of the font along with the base font for fallback. h.appendChild(s); var matched = (s.offsetWidth != defaultWidth[baseFonts[index]] || s.offsetHeight != defaultHeight[baseFonts[index]]); h.removeChild(s); detected = detected || matched; } return detected; } function addFont(family, stylesheetUrl, ruleString) { if (detect(family)) { //console.log('using internal font '+family); return true; } if (stylesheetUrl) { console.log('added stylesheet '+stylesheetUrl); var head = document.head, link = document.createElement('link'); link.type = 'text/css'; link.rel = 'stylesheet'; link.href = stylesheetUrl; head.appendChild(link); return true; } if (ruleString) { console.log('adding font rule:'+rule); var newStyle = document.createElement('style'); newStyle.appendChild(document.createTextNode(rule)); document.head.appendChild(newStyle); return true; } console.log('could not add font '+family); } function addFontsArr(arr) { arr.forEach(a => typeof a==='string' ? addFont(a) : addFont(a.family, a.stylesheetUrl, a.ruleString)); } };