Есть ли способ в javascript получить имена всех шрифтов (или семейств шрифтов), которые может отображать браузер? (Я хочу предоставить пользователю раскрывающийся список со списком всех доступных шрифтов и позволить пользователю выбрать шрифт.) Я бы предпочел не жестко кодировать этот список заранее или отправлять его с сервера. (Интуитивно кажется, что браузер должен знать, какие шрифты у него есть, и это как-то должно быть доступно для javascript.)
источник
Да, есть! Я так рад, что вы задали этот вопрос, потому что теперь я тоже хочу этим воспользоваться.
+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; };
Резюме
источник
Есть способ сделать это, используя
document.fonts
Возвращаемое значение - это интерфейс FontFaceSet документа. Интерфейс FontFaceSet полезен для загрузки новых шрифтов, проверки состояния ранее загруженных шрифтов и т. Д.
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)]; }
Я протестировал его, не связывая какие-либо шрифты в HTML, затем связал шрифт Roboto, снова протестировал, и он был добавлен к результату.
источник
Решение FontFaceSet.check ()
Список шрифтов Windows 10
'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',
Список шрифтов macOS / iOS
'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',
FontFaceSet.check ()
const fontCheck = new Set([ // Windows 10 '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', // macOS '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', ].sort()); (async() => { await document.fonts.ready; const fontAvailable = new Set(); for (const font of fontCheck.values()) { if (document.fonts.check(`12px "${font}"`)) { fontAvailable.add(font); } } console.log('Available Fonts:', [...fontAvailable.values()]); })();
источник
<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)); } };
источник
В своем поиске я также нашел Font.js , который добавляет объект Font, очень похожий на Image, поэтому можно проверить, действительно ли шрифт готов к использованию. Также работает с установленными / системными шрифтами. Обратной стороной является IE9 + только из-за необходимости
Object.defineProperty
(он есть в других браузерах), но если вы работаете в современном Интернете, это кажется еще лучшим вариантом. (К сожалению, мне придется пойти с ответом выше, проголосовать за него и двигаться дальше. :))источник
Короткий ответ. В отношении обнаружения шрифтов в браузерах в 2020 году мало что изменилось, за исключением того, что использование Flash стало еще хуже .
В настоящее время нет встроенной системы браузера для «перечисления» всех доступных шрифтов. Однако браузеры позволят вам проверить, загружен / готов ли шрифт, с помощью FontFaceSet API. . Он довольно хорошо поддерживается в современных браузерах.
Это предназначено для того, чтобы показать, полностью ли загружен веб-шрифт, НО он будет работать и для системных шрифтов. Загвоздка в том, что вам нужно предоставить список шрифтов для проверки.
Таким образом, в сочетании с
user agent
тестом (не всегда точным) вы можете составить список общих системных шрифтов для каждого типа устройства. Затем проверьте эти и любые загружаемые вами веб-шрифты.ПРИМЕЧАНИЕ. Это НЕ даст вам полный список доступных шрифтов, но вы можете проверить шрифты, обычно устанавливаемые продуктами MS Office или Adobe.
источник
Возможно, это можно было бы сделать совершенно другим способом, используя таблицу спрайтов с изображениями известных шрифтов для определенного символа и сравнивая это со снимками элемента холста, на котором тот же символ нарисован с тем же шрифтом, который обозреватель сообщает. Сравнение может быть выполнено с чем-то вроде подобия.js .
Это медленнее, но также должно позволить нам определить, когда браузер лжет.
источник
Недавно я заметил, что если я устанавливаю значение context.font для холста HTML5 на что-то недопустимое, например, «мусор», холст игнорирует это изменение. Я не знаю, зависит ли это от браузера, но похоже, что в Chrome это работает. Я также видел другие сообщения ( шрифт холста HTML 5 игнорируется ), в которых указывается, что это происходит в других браузерах.
Затем можно было бы написать строку со значением по умолчанию, которое, как мне кажется, является «10px sans serif» ( https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D/font ), установите шрифт к тому, который вы тестируете, и снова напишите строку. Если он такой же, как на первом рисунке, шрифт недоступен.
источник