我想使用 JavaScript 来计算字符串的宽度。这是否可能无需使用等宽字体?
如果它不是内置的,我唯一的想法是为每个字符创建一个宽度表,但这非常不合理,特别是支持 Unicode 和不同的字体大小(以及所有浏览器)。
原文由 Jacob 发布,翻译遵循 CC BY-SA 4.0 许可协议
我想使用 JavaScript 来计算字符串的宽度。这是否可能无需使用等宽字体?
如果它不是内置的,我唯一的想法是为每个字符创建一个宽度表,但这非常不合理,特别是支持 Unicode 和不同的字体大小(以及所有浏览器)。
原文由 Jacob 发布,翻译遵循 CC BY-SA 4.0 许可协议
在 HTML 5 中,您可以只使用 Canvas.measureText 方法( 此处 有进一步说明)。
/**
* Uses canvas.measureText to compute and return the width of the given text of given font in pixels.
*
* @param {String} text The text to be rendered.
* @param {String} font The css font descriptor that text is to be rendered with (e.g. "bold 14px verdana").
*
* @see https://stackoverflow.com/questions/118241/calculate-text-width-with-javascript/21015393#21015393
*/
function getTextWidth(text, font) {
// re-use canvas object for better performance
const canvas = getTextWidth.canvas || (getTextWidth.canvas = document.createElement("canvas"));
const context = canvas.getContext("2d");
context.font = font;
const metrics = context.measureText(text);
return metrics.width;
}
function getCssStyle(element, prop) {
return window.getComputedStyle(element, null).getPropertyValue(prop);
}
function getCanvasFont(el = document.body) {
const fontWeight = getCssStyle(el, 'font-weight') || 'normal';
const fontSize = getCssStyle(el, 'font-size') || '16px';
const fontFamily = getCssStyle(el, 'font-family') || 'Times New Roman';
return `${fontWeight} ${fontSize} ${fontFamily}`;
}
console.log(getTextWidth("hello there!", "bold 12pt arial")); // close to 86
如果你想使用某些特定元素的字体大小 myEl
,你可以使用 getCanvasFont
实用函数:
const fontSize = getTextWidth(text, getCanvasFont(myEl));
// do something with fontSize here...
说明: getCanvasFontSize
函数采用一些元素的(默认: body
的)字体并将其转换为与 Context.font 属性 兼容的格式。当然,任何元素在使用之前都必须首先添加到 DOM 中,否则它会给你虚假的值。
这种方法有几个优点,包括:
textAlign
和 textBaseline
可以进一步定制。注意:将文本添加到 DOM 时,请记住还要考虑 padding、margin 和 border 。
注 2:在某些浏览器上,此方法会产生亚像素精度(结果是一个浮点数),而在其他浏览器上则不会(结果只是一个 int)。您可能希望对结果运行 Math.floor
(或 Math.ceil
)以避免不一致。由于基于 DOM 的方法永远不会达到亚像素精度,因此该方法比此处的其他方法具有更高的精度。
根据 这个 jsperf (感谢评论中的贡献者), Canvas 方法 和 基于 DOM 的方法 差不多快,如果缓存被添加到 基于 DOM 的方法 并且你没有使用 Firefox。在 Firefox 中,出于某种原因,这种 Canvas 方法 比 基于 DOM 的方法 快得多(截至 2014 年 9 月)。
此小提琴 将此 Canvas 方法与 Bob Monteverde 基于 DOM 的方法 的变体进行比较,因此您可以分析和比较结果的准确性。
原文由 Domi 发布,翻译遵循 CC BY-SA 4.0 许可协议
13 回答13k 阅读
7 回答2.2k 阅读
3 回答1.3k 阅读✓ 已解决
6 回答1.3k 阅读✓ 已解决
2 回答1.4k 阅读✓ 已解决
3 回答1.4k 阅读✓ 已解决
6 回答1.1k 阅读
创建一个具有以下样式的 DIV。在您的 JavaScript 中,设置您要测量的字体大小和属性,将您的字符串放入 DIV,然后读取 DIV 的当前宽度和高度。它将拉伸以适应内容,并且大小将在字符串呈现大小的几个像素内。