当CSS font-face和font-size属性没有定义时,如何获得元素的实际字体和字体大小?例如,JavaScript代码段
font-face
font-size
object.style.fontFamily
不返回任何值。这是很明显的,假设CSS没有在任何地方对object应用样式。但是,当然,某种字体用于呈现文本,可能是系统字体或Web浏览器默认字体。那么,例如,JavaScript可以获得渲染的字体吗?
object
ar7v8xwq1#
我建议这个函数:
function css( element, property ) { return window.getComputedStyle( element, null ).getPropertyValue( property ); }
使用方法:
css( object, 'font-size' ) // returns '16px' for instance
注意:getComputedStyle在IE8中不工作。
getComputedStyle
现场演示:http://jsfiddle.net/4mxzE/
console.log( getComputedStyle(document.getElementById('test'), null) .getPropertyValue('font') )
#test { font-family: fantasy, cursive; }
<div id="test">Lorem ipsum dolor sit font-face</div>
bihw5rsg2#
没有一个标准的、可靠的方法来确定实际使用的字体。前面的答案将报告样式化的fontFamily样式值,但它可以是字体名称的列表,并不具体识别呈现的 * 实际 * 字体(这是这里提出的 * 实际 * 问题)。(As在一些评论中提到,有一些方法可以通过检查视觉线索来猜测字体,但这不太可能100%可靠。
t98cgbkg3#
您可以在Chrome/Firefox开发者工具中找到有关渲染字体的信息。请尝试检查以下代码片段中的段落:
p { font-family: sans-serif; }
<p>Some text and <span title="an emoji">😁</span></p>
在Chrome开发者工具(在55.0.2883.75 m 64位上测试)中,您可以获得以下信息:
在Firefox开发者工具(在47.0.2上用about:config > devtools.fontinspector.enabled = true测试)中,您可以获得以下信息:
about:config > devtools.fontinspector.enabled = true
ltqd579y4#
我找到了一种方法(适用于所有支持<canvas>的浏览器),如果字体呈现发生了变化,则逐个检查像素
<canvas>
function renderedfont(ele) { var getDefaultFonts = function () { var iframe = document.createElement('iframe'); var html = '<html><body>'; var fonts; document.body.appendChild(iframe); iframe.contentWindow.document.open(); iframe.contentWindow.document.write(html); var subele = iframe.contentWindow.document.createElement(ele.tagName); iframe.contentWindow.document.body.appendChild(subele); fonts = getComputedStyle(subele)['font-family']; document.body.removeChild(iframe); return fonts; } var fonts = getComputedStyle(ele)['font-family'] + ',' + getDefaultFonts(); var fontsArray = fonts.split(','); var canvas = document.createElement('canvas'); var ctx = canvas.getContext("2d"); var testString = "abcdefghijklmnopqrstuvwxyz!@#$%^&*()ñ"; var prevImageData; document.body.appendChild(canvas); canvas.width = 500; canvas.height = 300; fontsArray.unshift('"Font That Doesnt Exists ' + Math.random() + '"'); for (var i = 0; i < fontsArray.length; i++) { var fontName = fontsArray[i].trim(); ctx.clearRect(0, 0, canvas.width, canvas.height); ctx.font = '16px ' + fontName + ', monospace'; ctx.fillText(testString, 10, 100); var idata = ctx.getImageData(0, 0, canvas.width, canvas.height); var data = idata.data if (prevImageData) { for (var j = 0; j < data.length; j += 3) { if (prevImageData[j + 3] !== data[j + 3]) { document.body.removeChild(canvas); return fontName; } } } prevImageData = data; } document.body.removeChild(canvas); return 'monospace'; }
所以使用你只是做:
renderedfont(document.body); // Arial
如果你在使用另一种方言(例如日语),你可能需要将testString变量改为该方言中最常见的字符。
testString
r8uurelv5#
在这里有点晚了,但必须解决同样的问题...... Šime Vidas的答案基本上是正确的,但现在,你可以发挥创造力,并有你的答案。基本上,定义你自己的字体风格,你 * 确定 * 它不匹配任何现有的字体。然后,在每个computedstyle字体之后添加你的字体,看看它是否是你的字体得到渲染。如果不是,恭喜你,你找到了渲染的字体这是小提琴:https://jsfiddle.net/obutjanw/这是定义你需要的函数的代码:
(function(win) { var style = null; function createClass(name,rules){ if (typeof(rules)!="string") { rules = JSON.stringify(rules).trim(); } if (rules.startsWith("{")&&rules.endsWith("}")) { rules = rules.substring(1,rules.length-1); } if (style==null) { style = document.createElement('style'); style.type = 'text/css'; var head = document.getElementsByTagName('head'); if (head.length=0) { var h = document.createElement('head'); document.insertBefore(h,document.body); head = [h]; } head[0].appendChild(style); } var rule; if(!(style.sheet||{}).insertRule) { rule = (style.styleSheet || style.sheet).addRule(name, rules); } else { style.sheet.insertRule(name+"{"+rules+"}",0); rule = style.sheet } return rule; } function removeNode(node) { if (node.remove) { node.remove(); } else { var pn = node.parentElement; if (pn!=null) { pn.removeChild(node); } } } createClass("@font-face", "{ font-family: 'void'; src: url(data:application/font-woff2;charset=utf-8;base64,d09GMgABAAAAAAPQAA0AAAAAJLwAAAN2AAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP0ZGVE0cGh4GYACCehEICrcUtUcLgVYAATYCJAODGgQgBYQrB4IOGy8iyD4M2GTIPrT6WF2CYVmsrZSME0Lxo0HkLsnMe3J+bjz8/1jtvj/u6wnzjEfTZlY97lD30CyaNpNQaV4SibwX23xgzQx8YoKmJQvZq6ZBWjJtbams7UgryfyPub1/XCfUSbdKmihiPrNKphKi5QzxL7t7f4Ygsik2JcsCqWjBhCpFOWuA+r3/lb/f/ynl4AsvOYHFxycux78I1qIX+gd5kXU+ZsO7wLswbYM/aGDRxjV8TPCAshIIMC3BsAwDkAAb0NvIC+Bt1UII+PmLFgF/hd0tbtmBKvpAEsJFJIuEZDoXOdKdvlnrANSzuI5ODoqTBnPXWUMoMLdg3mfM5HgyMvzfCugCzEGQYQ45BQFX1ASmGBwDbTaYhJrjHt5r10f62D9QM6cHAk2AuaL8WWyod/QWEE4QLaFWFCqRyTS5fKGWdOtLt+d0B+sPBEPhSDQWTyRT6Uw2ly8US+VKtVZv8IIoyYqqQd9Ny3bcZqvd6fb6g+FoPJnO5ovlar3Z7vYA5ScZ7ex193Bz+4z/ClwC/AB8oXoA1Q/QBEggoUqTYA8V8QP3xWofHHUvrXZRqXfN8qbGV8YZV/BYWfkBegAgFnoLMY558+Pt8rg7Lt/z7D56vHHjeA/kHpUZZIyeL9n5vJD5V237BwsBgH8gRAhBCAmRRAYRurBwyYHg13/L7+pCvTFrmXM6isP3aQYoSiBYmswqCfwfekQgMH26vOBlp5nIt6nNIJs88OmzLcScJXAJBwUBOeW2FwjQk4KAkLULgaTgJAIZWZcRyMq6KUBOxX0B8rLeC1DT8waBuokUYKIpYQXQyFC0nUzq9pMZRReBLHKDzOlbk3lFr8maFR5HqdvkgxFXG6MrdRFjNCViJUaL5+QiVrjAwbN9F7h5QMLZB9QKuCbhOcOWi97AARc3ldBBDi8bFfJTmJ/1iItcwZOIMfIycmDvY6ScyfmvdqFTF5QimmrIbmrhJOdJlQqCBU9IMJG7EXVZ2rAZzfk/h3ThhdtKRD2rDSRULcKD5KXtU+4+qq9BUUlZRVVNXUOTnYOTi5sHjkCi0BgsjpePX0BQSFhEVExcQlJKWkZWTl5BUUlZRVVNXQNPIJLIFCqNwWSxOVxNLW0dXT19A0MjYxNTM3MLSytrG1s7ewffpMhE1htvffTO++5q7O2mciQwb+6tAgAAAA==) format('woff2'), url(data:application/font-woff;charset=utf-8;base64,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) format('woff'); }"); var tests = document.createElement("span"); tests.innerHTML = "0123"; tests.style.display = "inline-block"; tests.style.fontFamily = "void"; document.body.appendChild(tests); setTimeout(function() { removeNode(tests); },0); function getRenderedFontFamily(elm, computedstyle) { var cs = (typeof(computedstyle) == 'undefined') ? win.getComputedStyle(elm) : computedstyle; var fontF = (cs.fontFamily || elm.style['font-family'] || '').replace(/['"]*/g, ''); var tfontF = fontF.split(","); var tests = document.createElement("span"); tests.innerHTML = "0123"; tests.style.display = "inline-block"; tests.style.fontFamily = "void"; elm.appendChild(tests); var refcs = window.getComputedStyle(tests); var refw = refcs.width; var tested = {}; while (tfontF!=null) { for (var i=0;i<tfontF.length;i++) { if (tested[tfontF[i]]) continue; tests.style.fontFamily = tfontF[i] + ", void"; if (refcs.width!=refw) { removeNode(tests); return tfontF[i].trim(); } tested[tfontF[i]] = true; } if (elm.parentElement) { elm = elm.parentElement; var cs1 = win.getComputedStyle(elm); fontF = (cs1.fontFamily || elm.style['font-family'] || '').replace(/['"]*/g, ''); tfontF = fontF.split(","); } else { tfontF = null; } } removeNode(tests); } win.getRenderedFontFamily = getRenderedFontFamily; })(window);
请注意,如果一个节点使用的字体是在加载时追加的,那么您确实应该保留该部分,否则浏览器可能会在第一次调用getRenderedFontFamily时延迟呈现正确的字体
r6hnlfcb6#
有一种方法可以使用FontFaceSetcheck方法来确定加载的字体。
FontFaceSet
check
getComputedStyle(element).fontFamily .split(', ') .find(font => document.fonts.check(`10px ${font}`));
如果在您的情况下很重要,您可能还想在支票中添加字体样式/粗细。
但请注意,如果字体系列集包含无效的字体条目,则可能会返回错误的结果(请参阅文档https://developer.mozilla.org/en-US/docs/Web/API/FontFaceSet/check#nonexistent_fonts中的说明)。
6条答案
按热度按时间ar7v8xwq1#
我建议这个函数:
使用方法:
注意:
getComputedStyle
在IE8中不工作。现场演示:http://jsfiddle.net/4mxzE/
bihw5rsg2#
没有一个标准的、可靠的方法来确定实际使用的字体。前面的答案将报告样式化的fontFamily样式值,但它可以是字体名称的列表,并不具体识别呈现的 * 实际 * 字体(这是这里提出的 * 实际 * 问题)。
(As在一些评论中提到,有一些方法可以通过检查视觉线索来猜测字体,但这不太可能100%可靠。
t98cgbkg3#
您可以在Chrome/Firefox开发者工具中找到有关渲染字体的信息。请尝试检查以下代码片段中的段落:
在Chrome开发者工具(在55.0.2883.75 m 64位上测试)中,您可以获得以下信息:
在Firefox开发者工具(在47.0.2上用
about:config > devtools.fontinspector.enabled = true
测试)中,您可以获得以下信息:ltqd579y4#
我找到了一种方法(适用于所有支持
<canvas>
的浏览器),如果字体呈现发生了变化,则逐个检查像素所以使用你只是做:
如果你在使用另一种方言(例如日语),你可能需要将
testString
变量改为该方言中最常见的字符。r8uurelv5#
在这里有点晚了,但必须解决同样的问题...... Šime Vidas的答案基本上是正确的,但现在,你可以发挥创造力,并有你的答案。
基本上,定义你自己的字体风格,你 * 确定 * 它不匹配任何现有的字体。然后,在每个computedstyle字体之后添加你的字体,看看它是否是你的字体得到渲染。如果不是,恭喜你,你找到了渲染的字体
这是小提琴:https://jsfiddle.net/obutjanw/
这是定义你需要的函数的代码:
请注意,如果一个节点使用的字体是在加载时追加的,那么您确实应该保留该部分,否则浏览器可能会在第一次调用getRenderedFontFamily时延迟呈现正确的字体
r6hnlfcb6#
有一种方法可以使用
FontFaceSet
check
方法来确定加载的字体。如果在您的情况下很重要,您可能还想在支票中添加字体样式/粗细。
但请注意,如果字体系列集包含无效的字体条目,则可能会返回错误的结果(请参阅文档https://developer.mozilla.org/en-US/docs/Web/API/FontFaceSet/check#nonexistent_fonts中的说明)。