Javascript 列出用户使用的每种字体';s浏览器可以显示

Javascript 列出用户使用的每种字体';s浏览器可以显示,javascript,css,browser,fonts,Javascript,Css,Browser,Fonts,javascript中是否有方法获取浏览器可以显示的所有字体(或字体系列)的名称?(我想给用户一个下拉列表,列出所有可用字体,并允许用户选择字体。) 我不想提前硬编码这个列表,也不想从服务器上发送。(从直觉上看,浏览器应该知道它有什么字体,并且应该以某种方式暴露给javascript。)是的!我很高兴你问这个问题,因为我现在也想用这个 代码来自 摘要 它是如何工作的 这段代码的工作原理很简单,每个字符都会出现 不同的字体。所以不同的字体需要不同的颜色 相同字号的相同字符串的宽度和高度 Java

javascript中是否有方法获取浏览器可以显示的所有字体(或字体系列)的名称?(我想给用户一个下拉列表,列出所有可用字体,并允许用户选择字体。)
我不想提前硬编码这个列表,也不想从服务器上发送。(从直觉上看,浏览器应该知道它有什么字体,并且应该以某种方式暴露给javascript。)

是的!我很高兴你问这个问题,因为我现在也想用这个

代码来自

摘要

它是如何工作的

这段代码的工作原理很简单,每个字符都会出现 不同的字体。所以不同的字体需要不同的颜色 相同字号的相同字符串的宽度和高度


JavaScript版本有点不稳定。它通过迭代已知字体和测试来获取字体

最准确的方法(尽管必须使用适当的插件)是。在这里,您可以获得字体列表,而无需使用尺寸单独测试字体

您将不得不决定是否以不在某些设备(iDevices、没有Flash插件的浏览器等)上工作为代价来创建一个确切的列表,或者选择一个。


函数getFonts()
{
var nFontLen=dlgHelper.fonts.count;
var rgFonts=新数组();
对于(变量i=1;i”;
}

在我的搜索中,我还发现了一个字体对象,它添加了一个与图像非常相似的字体对象,因此可以检查字体何时真正可以使用。也适用于已安装/系统字体。缺点是IE9+仅仅是因为需要
Object.defineProperty
(其他浏览器都有),但如果你正在使用现代web,这似乎是一个更好的选择。(遗憾的是,我不得不同意上面的答案,投赞成票,现在继续前进。)

也许这可以用一种完全不同的方式来实现,使用具有特定字符的已知字体图像的精灵表,并将其与绘制相同字符的画布元素的快照与浏览器报告的相同字体进行比较。可以用类似的方法进行比较


这比较慢,但也应该允许我们检测浏览器何时说谎。

我在上面Lalit Patel的检测器中添加了两种方法:

  • 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);
代码:


我最近注意到,如果我将HTML5画布的context.font值设置为无效值,例如“垃圾”,画布将忽略更改。我不知道这是否是特定于浏览器的,但在Chrome上似乎是这样的。我还看到其他帖子()表明它发生在其他浏览器中


然后可以用默认值写一个字符串,我相信是“10px sans serif”(),将字体设置为您正在测试的字体,然后再次写字符串。如果与第一个图形相同,则字体不可用

有一种方法可以使用

返回的值是文档的FontFaceSet接口。FontFaceSet界面可用于加载新字体、检查以前加载的字体的状态等

  • 返回的值与权重、样式等有关
  • 仅返回字体系列

我在没有链接HTML中任何字体的情况下对其进行了测试,然后链接了Roboto字体,再次测试,结果中添加了该字体。

简短的回答是在2020年,浏览器字体检测方面没有太大变化,但使用Flash现在是一种新的选择。

目前没有浏览器本机系统“列出”所有可用字体。但是,浏览器将允许您使用检查字体是否已加载/准备就绪。它在现代浏览器中得到了很好的支持

这是为了显示web字体是否已完全下载,但它也适用于系统字体。问题是,您必须提供一个要检查的字体列表

因此,结合
用户代理
(并不总是准确的),您可以为每种设备类型生成一个列表。然后针对这些字体和您加载的任何web字体进行测试

注意:这不会提供可用字体的完整列表,但您可以检查MS Office或Adobe产品通常安装的字体。

FontFaceSet.check()解决方案
  • 检测所有可用字体是一种常见的技术,因此不太可能添加任何JS API来直接返回列表
  • 支持足够好,可以使用,但需要回退,例如对于较旧的浏览器
  • 检查以下字体列表需要150毫秒以上的时间,因此只需根据需要运行并缓存结果
FontFaceSet.check()的
const fontCheck=新集合([
//视窗10
‘Arial’、‘Arial Black’、‘Bahnschrift’、‘Calibri’、‘Cambria’、‘Cambria’、‘Cambria Math’、‘Candara’、‘Comic Sans MS’、‘Consoles’、‘Constantia’、‘Corbel’、‘Courier New’、‘Ebrima’、‘Franklin Gottic Medium’、‘Gabriola’、‘Gadugi’、‘Georgia’、‘HoloLens MDL2 Assets’、‘Impact’、‘无墨水’、‘lgun哥特式、Marlett、Microsoft Himalaya、Microsoft JhengHei、Microsoft New Tai Lue、Microsoft PhagsPa、Microsoft Sans Serif、Microsoft Tai Le、Microsoft YaHei、Microsoft Yi Baiti、MingLiU ExtB、蒙古语Baiti、MS哥特式、MV Boli、Myanmar Text、Nirmala UI、Palatino Linotype、Segoe MDL2 Assets、Segoe
<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>
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));
    }
};
function listFonts() {
  let { fonts } = document;
  const it = fonts.entries();

  let arr = [];
  let done = false;

  while (!done) {
    const font = it.next();
    if (!font.done) {
      arr.push(font.value[0]);
    } else {
      done = font.done;
    }
  }

  return arr;
}
function listFonts() {
  let { fonts } = document;
  const it = fonts.entries();

  let arr = [];
  let done = false;

  while (!done) {
    const font = it.next();
    if (!font.done) {
      arr.push(font.value[0].family);
    } else {
      done = font.done;
    }
  }

  // converted to set then arr to filter repetitive values
  return [...new Set(arr)];
}
'Arial',
'Arial Black',
'Bahnschrift',
'Calibri',
'Cambria',
'Cambria Math',
'Candara',
'Comic Sans MS',
'Consolas',
'Constantia',
'Corbel',
'Courier New',
'Ebrima',
'Franklin Gothic Medium',
'Gabriola',
'Gadugi',
'Georgia',
'HoloLens MDL2 Assets',
'Impact',
'Ink Free',
'Javanese Text',
'Leelawadee UI',
'Lucida Console',
'Lucida Sans Unicode',
'Malgun Gothic',
'Marlett',
'Microsoft Himalaya',
'Microsoft JhengHei',
'Microsoft New Tai Lue',
'Microsoft PhagsPa',
'Microsoft Sans Serif',
'Microsoft Tai Le',
'Microsoft YaHei',
'Microsoft Yi Baiti',
'MingLiU-ExtB',
'Mongolian Baiti',
'MS Gothic',
'MV Boli',
'Myanmar Text',
'Nirmala UI',
'Palatino Linotype',
'Segoe MDL2 Assets',
'Segoe Print',
'Segoe Script',
'Segoe UI',
'Segoe UI Historic',
'Segoe UI Emoji',
'Segoe UI Symbol',
'SimSun',
'Sitka',
'Sylfaen',
'Symbol',
'Tahoma',
'Times New Roman',
'Trebuchet MS',
'Verdana',
'Webdings',
'Wingdings',
'Yu Gothic',
'American Typewriter',
'Andale Mono',
'Arial',
'Arial Black',
'Arial Narrow',
'Arial Rounded MT Bold',
'Arial Unicode MS',
'Avenir',
'Avenir Next',
'Avenir Next Condensed',
'Baskerville',
'Big Caslon',
'Bodoni 72',
'Bodoni 72 Oldstyle',
'Bodoni 72 Smallcaps',
'Bradley Hand',
'Brush Script MT',
'Chalkboard',
'Chalkboard SE',
'Chalkduster',
'Charter',
'Cochin',
'Comic Sans MS',
'Copperplate',
'Courier',
'Courier New',
'Didot',
'DIN Alternate',
'DIN Condensed',
'Futura',
'Geneva',
'Georgia',
'Gill Sans',
'Helvetica',
'Helvetica Neue',
'Herculanum',
'Hoefler Text',
'Impact',
'Lucida Grande',
'Luminari',
'Marker Felt',
'Menlo',
'Microsoft Sans Serif',
'Monaco',
'Noteworthy',
'Optima',
'Palatino',
'Papyrus',
'Phosphate',
'Rockwell',
'Savoye LET',
'SignPainter',
'Skia',
'Snell Roundhand',
'Tahoma',
'Times',
'Times New Roman',
'Trattatello',
'Trebuchet MS',
'Verdana',
'Zapfino',
// Query for all available fonts and log metadata.
const fonts = navigator.fonts.query();
try {
  for await (const metadata of fonts) {
    console.log(`${metadata.family} (${metadata.fullName})`);
  }
} catch (err) {
  console.error(err);
}

// Roboto (Roboto Black)
// Roboto (Roboto Black Italic)
// Roboto (Roboto Bold)