用 JavaScript 计算文本宽度

新手上路,请多包涵

我想使用 JavaScript 来计算字符串的宽度。这是否可能无需使用等宽字体?

如果它不是内置的,我唯一的想法是为每个字符创建一个宽度表,但这非常不合理,特别是支持 Unicode 和不同的字体大小(以及所有浏览器)。

原文由 Jacob 发布,翻译遵循 CC BY-SA 4.0 许可协议

阅读 2k
2 个回答

创建一个具有以下样式的 DIV。在您的 JavaScript 中,设置您要测量的字体大小和属性,将您的字符串放入 DIV,然后读取 DIV 的当前宽度和高度。它将拉伸以适应内容,并且大小将在字符串呈现大小的几个像素内。

 var fontSize = 12;
 var test = document.getElementById("Test");
 test.style.fontSize = fontSize;
 var height = (test.clientHeight + 1) + "px";
 var width = (test.clientWidth + 1) + "px"

 console.log(height, width);
 #Test
 {
 position: absolute;
 visibility: hidden;
 height: auto;
 width: auto;
 white-space: nowrap; /* Thanks to Herb Caudill comment */
 }
 <div id="Test">
 abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ
 </div>

原文由 CMPalmer 发布,翻译遵循 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 中,否则它会给你虚假的值。

更多注意事项

这种方法有几个优点,包括:

  • 比其他(基于 DOM 的)方法更简洁、更安全,因为它不会更改全局状态,例如您的 DOM。
  • 通过 修改更多的画布文本属性,例如 textAligntextBaseline 可以进一步定制。

注意:将文本添加到 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 许可协议

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题