我想使用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 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
如果你想使用特定元素myl的字体大小,你可以使用getCanvasFont实用函数:
const fontSize = getTextWidth(text, getCanvasFont(myEl));
// do something with fontSize here...
解释:getCanvasFontSize函数接受某些元素的字体(默认为正文),并将其转换为与上下文兼容的格式。字体属性。当然,任何元素在使用之前都必须首先添加到DOM中,否则会给您虚假的值。
更多的笔记
这种方法有几个优点,包括:
比其他(基于DOM的)方法更简洁和更安全,因为它不改变全局状态,比如DOM。 进一步的定制可以通过修改更多的画布文本属性,如textAlign和textBaseline。
注意:当你在DOM中添加文本时,记住还要考虑到填充、边距和边框。
注2:在某些浏览器上,该方法产生亚像素精度(结果是浮点数),在其他浏览器上则不是(结果只是一个int)。你可能想运行数学。floor(或Math.ceil),以避免不一致。由于基于dom的方法从来没有亚像素精度,因此该方法比这里的其他方法具有更高的精度。
根据这个jsperf(感谢评论中的贡献者),如果将缓存添加到基于dom的方法中,并且您没有使用Firefox,那么Canvas方法和基于dom的方法几乎一样快。在Firefox中,由于某种原因,这种Canvas方法要比基于dom的方法快得多(截至2014年9月)。
性能
本文将此Canvas方法与Bob Monteverde基于dom的方法的变体进行了比较,因此您可以分析和比较结果的准确性。
其他回答
这对我很有用……
// 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.textContent = pText;
var lResult = {
width: lDiv.clientWidth,
height: lDiv.clientHeight
};
document.body.removeChild(lDiv);
lDiv = null;
return lResult;
}
这是我随手拼凑的一个例子。看来我们都达成共识了。
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()
**增加了空格:nowrap,因此宽度大于窗口宽度的字符串可以被计算。
您可以使用max-content来测量文本的像素宽度。
这是一个效用函数。它可以选择将任何节点作为上下文来计算宽度,考虑到任何CSS,如字体大小、字母间距等。
function measureTextPxWidth( text, template = document.createElement("span") ) { const measurer = template.cloneNode(); measurer.style.setProperty("all", "revert", "important"); measurer.style.setProperty("position", "position", "important"); measurer.style.setProperty("visibility", "hidden", "important"); measurer.style.setProperty("width", "max-content", "important"); measurer.innerText = text; document.body.appendChild(measurer); const { width } = measurer.getBoundingClientRect(); document.body.removeChild(measurer); return width; } document.querySelector('.spanTextWidth').innerText = `${measureTextPxWidth('one two three')}px` document.querySelector('.h1TextWidth').innerText = `${measureTextPxWidth('one two three', document.querySelector('h1'))}px` h1 { letter-spacing: 3px; } <span>one two three</span> <div class="spanTextWidth"></div> <h1>one two three</h1> <div class="h1TextWidth"></div>
在文本的包含元素上使用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来测量更复杂内容的大小。
var textWidth = (function (el) {
el.style.position = 'absolute';
el.style.top = '-1000px';
document.body.appendChild(el);
return function (text) {
el.innerHTML = text;
return el.clientWidth;
};
})(document.createElement('div'));