我想使用JavaScript来计算字符串的宽度。如果不使用单行字体,这可能吗?
如果它不是内置的,我唯一的想法是为每个字符创建一个宽度表,但这是非常不合理的,特别是支持Unicode和不同的类型大小(以及所有浏览器)。
我想使用JavaScript来计算字符串的宽度。如果不使用单行字体,这可能吗?
如果它不是内置的,我唯一的想法是为每个字符创建一个宽度表,但这是非常不合理的,特别是支持Unicode和不同的类型大小(以及所有浏览器)。
当前回答
更好的方法是在显示元素之前检测文本是否合适。你可以使用这个函数它不需要元素在屏幕上。
function textWidth(text, fontProp) {
var tag = document.createElement("div");
tag.style.position = "absolute";
tag.style.left = "-999em";
tag.style.whiteSpace = "nowrap";
tag.style.font = fontProp;
tag.innerHTML = text;
document.body.appendChild(tag);
var result = tag.clientWidth;
document.body.removeChild(tag);
return result;
}
用法:
if ( textWidth("Text", "bold 13px Verdana") > elementWidth) {
...
}
其他回答
你也可以使用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;
}
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);
我使用文本度量包。工作真的很好,我尝试了这个解决方案,但在某些原因,它计算错误。
textMetrics.init(document.querySelector('h1'), { fontSize: '20px' });
textMetrics.init({
fontSize: '14px',
lineHeight: '20px',
fontFamily: 'Helvetica, Arial, sans-serif',
fontWeight: 400,
width: 100,
});
用下面的样式创建一个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 >
从头重写了我的答案(谢谢你的减分)。 现在函数接受一个文本和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>