我想使用JavaScript来计算字符串的宽度。如果不使用单行字体,这可能吗?
如果它不是内置的,我唯一的想法是为每个字符创建一个宽度表,但这是非常不合理的,特别是支持Unicode和不同的类型大小(以及所有浏览器)。
我想使用JavaScript来计算字符串的宽度。如果不使用单行字体,这可能吗?
如果它不是内置的,我唯一的想法是为每个字符创建一个宽度表,但这是非常不合理的,特别是支持Unicode和不同的类型大小(以及所有浏览器)。
当前回答
对于任何一个在那里使用React和/或Typescript…
试试这个Codepen!
export default function App() {
const spanRef = useRef<HTMLSpanElement>(null);
const [textWidth, setTextWidth] = useState(0);
const getTextWidthInPixels = (ref: HTMLSpanElement) =>
ref.getBoundingClientRect().width;
useEffect(() => {
setTextWidth(getTextWidthInPixels(spanRef.current!));
}, [spanRef]);
return (
<div className="App">
<span
ref={spanRef}
contentEditable
suppressContentEditableWarning
onInput={() => setTextWidth(getTextWidthInPixels(spanRef.current!))}
>
Edit Me!!!
</span>
{`textWidth: ${textWidth}px`}
</div>
);
}
将文本包装在内联定位的元素(如<span>)中是个好主意。 useRef是React访问DOM元素的方式,在我们的例子中是<span> getBoundingClientRect可以获得任何DOM元素的总宽度。 contentteditable允许用户更改元素的内容…这有点不安全(React会抛出警告!) suppresscontentteditablewarning将帮助我们防止这些警告
其他回答
从头重写了我的答案(谢谢你的减分)。 现在函数接受一个文本和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>
用下面的样式创建一个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 >
您可以使用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>
你也可以使用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;
}
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'));