我想使用JavaScript来计算字符串的宽度。如果不使用单行字体,这可能吗?
如果它不是内置的,我唯一的想法是为每个字符创建一个宽度表,但这是非常不合理的,特别是支持Unicode和不同的类型大小(以及所有浏览器)。
我想使用JavaScript来计算字符串的宽度。如果不使用单行字体,这可能吗?
如果它不是内置的,我唯一的想法是为每个字符创建一个宽度表,但这是非常不合理的,特别是支持Unicode和不同的类型大小(以及所有浏览器)。
当前回答
根据Deepak Nadar的回答,我修改了函数参数,以接受文本和字体样式。您不需要引用元素。此外,fontOptions有默认值,所以您不需要提供所有的选项。
(function($) { $.format = function(format) { return (function(format, args) { return format.replace(/{(\d+)}/g, function(val, pos) { return typeof args[pos] !== 'undefined' ? args[pos] : val; }); }(format, [].slice.call(arguments, 1))); }; $.measureText = function(html, fontOptions) { fontOptions = $.extend({ fontSize: '1em', fontStyle: 'normal', fontWeight: 'normal', fontFamily: 'arial' }, fontOptions); var $el = $('<div>', { html: html, css: { position: 'absolute', left: -1000, top: -1000, display: 'none' } }).appendTo('body'); $(fontOptions).each(function(index, option) { $el.css(option, fontOptions[option]); }); var h = $el.outerHeight(), w = $el.outerWidth(); $el.remove(); return { height: h, width: w }; }; }(jQuery)); var dimensions = $.measureText("Hello World!", { fontWeight: 'bold', fontFamily: 'arial' }); // Font Dimensions: 94px x 18px $('body').append('<p>').text($.format('Font Dimensions: {0}px x {1}px', dimensions.width, dimensions.height)); <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
其他回答
下面的代码片段,“计算”span标签的宽度,如果它太长,就添加“…”,并减少文本长度,直到它适合它的父标签(或者直到它尝试了超过1000次)
CSS
div.places {
width : 100px;
}
div.places span {
white-space:nowrap;
overflow:hidden;
}
HTML
<div class="places">
<span>This is my house</span>
</div>
<div class="places">
<span>And my house are your house</span>
</div>
<div class="places">
<span>This placename is most certainly too wide to fit</span>
</div>
JavaScript(使用jQuery)
// loops elements classed "places" and checks if their child "span" is too long to fit
$(".places").each(function (index, item) {
var obj = $(item).find("span");
if (obj.length) {
var placename = $(obj).text();
if ($(obj).width() > $(item).width() && placename.trim().length > 0) {
var limit = 0;
do {
limit++;
placename = placename.substring(0, placename.length - 1);
$(obj).text(placename + "...");
} while ($(obj).width() > $(item).width() && limit < 1000)
}
}
});
没有jQuery:
String.prototype.width = function (fontSize) {
var el,
f = fontSize + " px arial" || '12px arial';
el = document.createElement('div');
el.style.position = 'absolute';
el.style.float = "left";
el.style.whiteSpace = 'nowrap';
el.style.visibility = 'hidden';
el.style.font = f;
el.innerHTML = this;
el = document.body.appendChild(el);
w = el.offsetWidth;
el.parentNode.removeChild(el);
return w;
}
// Usage
"MyString".width(12);
从头重写了我的答案(谢谢你的减分)。 现在函数接受一个文本和css规则被应用(不再使用jQuery)。所以它也会尊重填充。结果值被四舍五入(您可以看到Math。四舍五入,如果你想要更精确的值,可以去掉)
function getSpan(){ const span = document.createElement('span') span.style.position = 'fixed'; span.style.visibility = 'hidden'; document.body.appendChild(span); return span; } function textWidth(str, css) { const span = getSpan(); Object.assign(span.style, css || {}); span.innerText = str; const w = Math.round(span.getBoundingClientRect().width); span.remove(); return w; } const testStyles = [ {fontSize: '10px'}, {fontSize: '12px'}, {fontSize: '60px'}, {fontSize: '120px'}, {fontSize: '120px', padding: '10px'}, {fontSize: '120px', fontFamily: 'arial'}, {fontSize: '120px', fontFamily: 'tahoma'}, {fontSize: '120px', fontFamily: 'tahoma', padding: '5px'}, ]; const ul = document.getElementById('output'); testStyles.forEach(style => { const li = document.createElement('li'); li.innerText = `${JSON.stringify(style)} > ${textWidth('abc', style)}`; ul.appendChild(li); }); <ul id="output"></ul>
如果有人在这里寻找一种测量字符串宽度的方法,以及一种知道适合特定宽度的最大字体大小的方法,这里有一个基于@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;
}
}
}
嘿,大家,我知道我来晚了一点,但我们开始吧
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