我想使用 JavaScript 来计算字符串的宽度。这是否可能而不必使用等宽字体?
如果它不是内置的,我唯一的想法是为每个字符创建一个宽度表,但这非常不合理,尤其是支持Unicode和不同的类型大小(以及所有浏览器)。
我想使用 JavaScript 来计算字符串的宽度。这是否可能而不必使用等宽字体?
如果它不是内置的,我唯一的想法是为每个字符创建一个宽度表,但这非常不合理,尤其是支持Unicode和不同的类型大小(以及所有浏览器)。
在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 getCanvasFontSize(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
,可以使用getCanvasFontSize
实用程序功能:
const fontSize = getTextWidth(text, getCanvasFontSize(myEl));
// do something with fontSize here...
说明:该getCanvasFontSize
函数采用一些元素的(默认为body
's)字体并将其转换为与Context.font 属性兼容的格式。当然,任何元素在使用之前都必须先添加到 DOM 中,否则它会给你虚假的值。
这种方法有几个优点,包括:
textAlign
和 ),可以进一步自定义textBaseline
。注意:当您将文本添加到 DOM 时,请记住还要考虑padding、margin 和 border。
注意 2:在某些浏览器上,此方法会产生亚像素精度(结果是一个浮点数),而在其他浏览器上则不会(结果只是一个整数)。您可能希望对结果运行Math.floor
(或Math.ceil
),以避免不一致。由于基于 DOM 的方法从来都不是亚像素精确的,因此该方法比这里的其他方法具有更高的精度。
根据这个 jsperf(感谢评论中的贡献者),如果将缓存添加到基于 DOM 的方法并且您没有使用 Firefox ,则Canvas 方法和基于 DOM 的方法的速度差不多。在 Firefox 中,出于某种原因,这种Canvas 方法比基于 DOM 的方法(截至 2014 年 9 月)快得多。
此小提琴将 Canvas 方法与Bob Monteverde 的基于 DOM 的方法的变体进行比较,因此您可以分析和比较结果的准确性。
创建具有以下样式的 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>
这是我在没有例子的情况下鞭打的。看起来我们都在同一页面上。
String.prototype.width = function(font) {
var f = font || '12px arial',
o = $('<div></div>')
.text(this)
.css({'position': 'absolute', 'float': 'left', 'white-space': 'nowrap', 'visibility': 'hidden', 'font': f})
.appendTo($('body')),
w = o.width();
o.remove();
return w;
}
使用它很简单: "a string".width()
**添加white-space: nowrap
以便可以计算宽度大于窗口宽度的字符串。
这对我有用...
// Handy JavaScript to measure the size taken to render the supplied text;
// you can supply additional style information too if you have it.
function measureText(pText, pFontSize, pStyle) {
var lDiv = document.createElement('div');
document.body.appendChild(lDiv);
if (pStyle != null) {
lDiv.style = pStyle;
}
lDiv.style.fontSize = "" + pFontSize + "px";
lDiv.style.position = "absolute";
lDiv.style.left = -1000;
lDiv.style.top = -1000;
lDiv.innerHTML = pText;
var lResult = {
width: lDiv.clientWidth,
height: lDiv.clientHeight
};
document.body.removeChild(lDiv);
lDiv = null;
return lResult;
}
jQuery:
(function($) {
$.textMetrics = function(el) {
var h = 0, w = 0;
var div = document.createElement('div');
document.body.appendChild(div);
$(div).css({
position: 'absolute',
left: -1000,
top: -1000,
display: 'none'
});
$(div).html($(el).html());
var styles = ['font-size','font-style', 'font-weight', 'font-family','line-height', 'text-transform', 'letter-spacing'];
$(styles).each(function() {
var s = this.toString();
$(div).css(s, $(el).css(s));
});
h = $(div).outerHeight();
w = $(div).outerWidth();
$(div).remove();
var ret = {
height: h,
width: w
};
return ret;
}
})(jQuery);