Apakah ada cara dalam javascript untuk mendapatkan nama semua font (atau font-family) yang dapat ditampilkan oleh browser? (Saya ingin memberikan dropdown kepada pengguna dengan daftar semua font yang tersedia, dan mengizinkan pengguna untuk memilih font.) Saya lebih suka untuk tidak melakukan hardcode daftar ini sebelumnya atau mengirimkannya dari server. (Secara intuitif, sepertinya browser harus tahu font apa yang dimilikinya dan ini harus diekspos ke javascript.)
sumber
Ya ada! Saya sangat senang Anda menanyakan pertanyaan ini karena sekarang saya ingin menggunakan ini juga.
+1 untuk pertanyaan, dan inilah jawaban Anda :)
http://www.lalit.org/lab/javascript-css-font-detect
Kode dari 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; };
Ringkasan
sumber
Ada cara untuk melakukan ini dengan menggunakan
document.fonts
Nilai yang dikembalikan adalah antarmuka FontFaceSet dokumen. Antarmuka FontFaceSet berguna untuk memuat font baru, memeriksa status font yang dimuat sebelumnya, dll.
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)]; }
Saya telah mengujinya tanpa menautkan font apa pun di HTML, lalu menautkan font Roboto, menguji lagi dan itu ditambahkan ke hasil.
sumber
Solusi FontFaceSet.check ()
Daftar Font 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',
Daftar Font 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()]); })();
sumber
<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>
sumber
Saya menambahkan dua metode ke Detektor Lalit Patel di atas:
Dengan ini, Anda dapat melakukan:
fonts = [ 'Arial', 'Arial Black', { family: 'Lato', stylesheetUrl: 'https://fonts.googleapis.com/css?family=Lato'}, 'Leelawadee UI'] (new FontDetector()).addFontsArr(fonts);
kode:
/** * 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)); } };
sumber
Dalam pencarian saya untuk ini, saya juga menemukan Font.js , yang menambahkan objek Font seperti Image, jadi mungkin untuk memeriksa kapan font benar-benar siap digunakan. Juga berfungsi pada font terinstal / sistem. Kelemahannya adalah IE9 + hanya karena membutuhkan
Object.defineProperty
(browser lain memilikinya), tetapi jika Anda menggunakan web modern, ini sepertinya pilihan yang lebih baik. (Saya akan, sayangnya, harus melanjutkan dengan jawaban di atas, mendapat suara positif dan melanjutkan untuk saat ini. :))sumber
Jawaban singkatnya adalah. Tidak banyak yang berubah terkait deteksi font di browser pada tahun 2020 kecuali bahwa menggunakan Flash sekarang merupakan ide yang lebih buruk .
Saat ini tidak ada sistem asli browser untuk "mencantumkan" semua font yang tersedia. Namun, browser akan membiarkan Anda memeriksa apakah font telah dimuat / siap menggunakan API FontFaceSet . Ini didukung dengan cukup baik di browser modern.
Ini dimaksudkan untuk menunjukkan apakah font web telah diunduh sepenuhnya TETAPI itu akan berfungsi untuk font sistem juga. Tangkapannya adalah Anda harus memberikan daftar font untuk diperiksa.
Jadi sehubungan dengan
user agent
pengujian (tidak selalu akurat), Anda dapat membuat daftar font sistem umum untuk setiap jenis perangkat. Kemudian uji terhadap itu dan font web apa pun yang Anda muat.CATATAN: Ini TIDAK akan memberi Anda daftar lengkap font yang tersedia, tetapi Anda dapat memeriksa font yang biasa diinstal oleh produk MS Office atau Adobe.
sumber
Mungkin ini bisa dilakukan dengan cara yang sama sekali berbeda, menggunakan spritesheet dengan gambar font yang diketahui untuk karakter tertentu dan membandingkannya dengan snapshot dari elemen kanvas di mana karakter yang sama digambar dengan apa yang dilaporkan browser sebagai font yang sama. Perbandingan dapat dilakukan dengan sesuatu seperti menyerupai js .
Ini lebih lambat, tetapi juga memungkinkan kami untuk mendeteksi saat browser berbohong.
sumber
Saya baru-baru ini memperhatikan bahwa jika saya menyetel nilai context.font untuk kanvas HTML5, ke sesuatu yang tidak valid, seperti "sampah", perubahan tersebut diabaikan oleh kanvas. Saya tidak tahu apakah ini khusus browser, tetapi tampaknya berfungsi seperti ini di Chrome. Saya juga melihat posting lain ( font kanvas HTML 5 diabaikan ) yang menunjukkan itu terjadi di browser lain.
Seseorang kemudian dapat menulis string dengan nilai default, yang saya yakini adalah "10px sans serif" ( https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D/font ), mengatur font ke salah satu yang Anda uji dan tulis string lagi. Jika sama dengan gambar pertama, maka font tidak tersedia.
sumber