javascript - attribute - enumera cada fuente que el navegador de un usuario puede mostrar
title html (6)
¡Sí hay! Estoy muy contento de que hayas hecho esta pregunta porque ahora quiero usar esto también.
+1 por pregunta, y esta es tu respuesta :)
http://www.lalit.org/lab/javascript-css-font-detect
Código de 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;
};
Resumen
¿Como funciona?
Este código funciona según el principio simple de que cada personaje aparece de forma diferente en fuentes diferentes. Por lo tanto, diferentes tipos de letra tomarán diferente ancho y alto para la misma cadena de caracteres del mismo tamaño de fuente.
¿Hay alguna forma en javascript para obtener los nombres de todas las fuentes (o familias de fuentes) que el navegador puede mostrar? (Quiero darle al usuario un menú desplegable con una lista de todas las fuentes disponibles, y permitir que el usuario elija una fuente). Preferiría no tener que codificar esta lista por adelantado o enviarla desde el servidor. (Intuitivamente, parece que el navegador debe saber qué fuentes tiene y esto debería estar expuesto a javascript de alguna manera).
Agregué dos métodos al Detector de Lalit Patel arriba:
- addFont (family, stylesheetUrl, ruleString) -> detecta si la fuente ''family'' existe, si no agrega una hoja de estilo cargando la fuente usando cualquiera stylesheetUrl si se le da o de otra forma ruleString
- addFontsArr (arr) -> agrega una matriz de fuentes
Con esto puedes hacer:
fonts = [ ''Arial'', ''Arial Black'', { family: ''Lato'', stylesheetUrl: ''https://fonts.googleapis.com/css?family=Lato''}, ''Leelawadee UI'']
(new FontDetector()).addFontsArr(fonts);
código:
/**
* 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));
}
};
En mi búsqueda de esto, también encontré Font.js , que agrega un objeto Font muy similar a Image, por lo que es posible verificar cuándo una fuente está realmente lista para usar. También funciona en fuentes instaladas / del sistema. Downside es IE9 + solo debido a que necesita Object.defineProperty
(otros navegadores lo tienen), pero si está haciendo una web moderna, esta parece ser una opción aún mejor. (Por desgracia, tendré que ir con la respuesta anterior, upvoted y seguir adelante por ahora :))
La versión de JavaScript es un poco escamosa. Obtiene fuentes iterando a través de fuentes y pruebas conocidas.
La forma más precisa (aunque teniendo que usar un plugin de propiedad) es usar Flash . Aquí puede obtener la lista de fuentes sin tener que probarlas individualmente usando las dimensiones.
Tendrá que decidir si desea tener una lista exacta a expensas de no trabajar en algunos dispositivos (iDevices, navegadores sin complemento Flash, etc.), o una lista parcial con mejor soporte a través de JavaScript solamente .
Tal vez esto podría hacerse de una forma completamente diferente, utilizando una hoja de sprites con imágenes de fuentes conocidas para un personaje específico y comparándola con instantáneas de un elemento canvas en el que se dibuja el mismo personaje con lo que el navegador informa como la misma fuente. La comparación se puede hacer con algo parecido a resemble.js .
Esto es más lento, pero también debería permitirnos detectar cuándo está mintiendo el navegador.
<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>