我想使用JavaScript来计算字符串的宽度。如果不使用单行字体,这可能吗?

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


当前回答

在文本的包含元素上使用scrollWidth来获得元素的最小宽度,包括由于溢出而隐藏的部分。更多信息请访问https://developer.mozilla.org/en-US/docs/Web/API/Element/scrollWidth

如果元素不在DOM中,将其添加到某个隐藏区域以进行测量。例如:

function measureText(text) {
  let div = document.createElement("div");
  div.innerText = text;
  div.style.whiteSpace = 'nowrap';
  body.appendChild(div);
  let width = div.scrollWidth;
  body.removeChild(div);
  return width;
}

样式(字体大小、重量等)将被元素继承,因此计入宽度。您还可以使用scrollWidth和scrollHeight来测量更复杂内容的大小。

其他回答

你可以使用画布,这样你就不必处理这么多css属性:

var canvas = document.createElement("canvas");
var ctx = canvas.getContext("2d");
ctx.font = "20pt Arial";  // This can be set programmaticly from the element's font-style if desired
var textWidth = ctx.measureText($("#myElement").text()).width;

你也可以使用createRange,这比文本克隆技术更准确:

function getNodeTextWidth(nodeWithText) {
    var textNode = $(nodeWithText).contents().filter(function () {
        return this.nodeType == Node.TEXT_NODE;
    })[0];
    var range = document.createRange();
    range.selectNode(textNode);
    return range.getBoundingClientRect().width;
}

如果有人在这里寻找一种测量字符串宽度的方法,以及一种知道适合特定宽度的最大字体大小的方法,这里有一个基于@Domi的解决方案的函数,使用二进制搜索:

/**
 * Find the largest font size (in pixels) that allows the string to fit in the given width.
 * 
 * @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 ?px verdana") -- note the use of ? in place of the font size.
 * @param {Number} width - The width in pixels the string must fit in
 * @param {Number} minFontPx - The smallest acceptable font size in pixels
 * @param {Number} maxFontPx - The largest acceptable font size in pixels
 **/
function GetTextSizeForWidth(text, font, width, minFontPx, maxFontPx) {
  for (;;) {
    var s = font.replace("?", maxFontPx);
    var w = GetTextWidth(text, s);
    if (w <= width) {
      return maxFontPx;
    }

    var g = (minFontPx + maxFontPx) / 2;

    if (Math.round(g) == Math.round(minFontPx) || Math.round(g) == Math.round(maxFontPx)) {
      return g;
    }

    s = font.replace("?", g);
    w = GetTextWidth(text, s);
    if (w >= width) {
      maxFontPx = g;
    } else {
      minFontPx = g;
    }
  }
}

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

var fontSize = 12; var test = document.getElementById(" test "); test.style.fontSize = fontSize; Var高度= (test。clientHeight + 1) + "px"; Var宽度=(测试。clientWidth + 1) + "px" console.log(高度、宽度); #测试 { 位置:绝对的; 可见性:隐藏; 高度:汽车; 宽度:汽车; 空白:nowrap;}/*感谢Herb Caudill的评论*/ } < div id = "测试" > abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ < / div >

嘿,大家,我知道我来晚了一点,但我们开始吧

window.addEventListener("error",function(e){ alert(e.message); });
var canvas = new OffscreenCanvas(400, 50);
var ctx = canvas.getContext("2d");
ctx.font = "16px Ariel"; //this can be dynamic using getComputedStyle
const chars = ["a","b","c","d","e","f"," ","    "];
const charWidths = new Map();
while(chars.length > 0){
  var char = chars.shift();
  var wide = ctx.measureText(char).width;
  charWidths.set(char,wide);
}

然后你可以用它来做如下的事情:

var pixelWidth = charWidths.get("0");
//fyi css properties like letter-spacing need to be accounted for