перечислите каждый шрифт, который может отображать браузер пользователя - PullRequest
80 голосов
/ 30 июля 2010

Есть ли в javascript способ получить имена всех шрифтов (или семейств шрифтов), которые может отображать браузер? (Я хочу предоставить пользователю выпадающий список со всеми доступными шрифтами и позволить пользователю выбрать шрифт.) Я предпочел бы, чтобы мне не приходилось жестко кодировать этот список заранее или отправлять его с сервера. (Интуитивно кажется, что браузер должен знать, какие у него шрифты, и это должно как-то быть подвержено JavaScript).

Ответы [ 7 ]

60 голосов
/ 30 июля 2010

Да, есть!Я так рад, что вы задали этот вопрос, потому что теперь я тоже хочу использовать его.

+ 1 для вопроса, и вот ваш ответ:)

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

Код из http://www.lalit.org/wordpress/wp-content/uploads/2008/05/fontdetect.js?ver=0.3

/**
 * 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;
};

Резюме

Как это работает?

Этот код работаетпо простому принципу, что каждый символ появляется по-разному в разных шрифтах.Таким образом, разные шрифты будут иметь разную ширину и высоту для одной и той же строки символов одинакового размера шрифта.

31 голосов
/ 30 июля 2010

Версия JavaScript немного ненадежна. Он получает шрифты путем перебора известных шрифтов и тестирования.

Самый точный способ (хотя и использовать плагин правильности) - использовать Flash . Здесь вы можете получить список шрифтов, не проверяя их по отдельности, используя размеры.

Вам нужно решить, иметь ли точный список за счет отсутствия работы на некоторых устройствах (iDevices, браузерах без Flash-плагина и т. Д.), Или частичный список с лучшей поддержкой только через JavaScript .

3 голосов
/ 15 июня 2011
<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>
2 голосов
/ 22 марта 2017

Я добавил два метода к Детектору Лалита Пателя выше:

  • 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));
    }
};
2 голосов
/ 21 сентября 2014

В моем поиске я также нашел Font.js , который добавляет объект Font, очень похожий на Image, так что можно проверить, когда шрифт действительно готов к использованию. Также работает на установленных / системных шрифтах. Недостатком является IE9 + только из-за необходимости Object.defineProperty (есть в других браузерах), но если вы работаете в современном Интернете, это кажется еще лучшим вариантом. (К сожалению, мне придется идти с ответом выше, голосовать и двигаться дальше. :))

0 голосов
/ 02 июля 2019

Перейдите на deviceinfo.me и нажмите кнопку обнаружения шрифта.

0 голосов
/ 01 марта 2017

Может быть, это можно сделать совершенно по-другому, используя таблицу спрайтов с изображениями известных шрифтов для конкретного символа и сравнивая ее со снимками элемента холста, на котором нарисован тот же символ, с тем, что браузер сообщает как тот же шрифт,Сравнение может быть сделано с чем-то вроде resemble.js .

Это медленнее, но также должно позволить нам определять, когда браузер лежит.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...