我想喜欢接受的答案,但从根本上说,符合我的标准的答案都需要使用图书馆。我决定编写一个非常适合我的简单函数,而不是让自己熟悉另一个库,然后找出如何使用它并准备在它不工作时进行调试。
理论:
传入需要匹配的字符串传入要从中继承文本样式的父级可选地传入自定义属性(例如,您将从中继承字体和其他属性的类/id,或者仅传入自定义内联样式)函数将在屏幕外创建一个文本元素,其中包含该文本、该父元素和这些属性,字体大小为1px,并对其进行测量然后,在循环中,它将逐像素增加字体大小,直到超过宽度限制;一旦完成,它将返回最后一个合适的然后删除测试元素当然,这一切都发生在眨眼之间
限制:
我不在乎动态调整屏幕大小,因为这与我的上下文无关。在生成文本时,我只关心运行时的屏幕大小。我依赖一个小助手函数,我也在代码的其他地方使用它,它基本上作为mithril.js的单函数版本存在;老实说,我几乎在每个项目中都使用这个小功能,它值得自己学习。
function findMaxFontSize(
string="a string",
parent=document.body,
attributes={id:'font-size-finder',class:'some-class-with-font'}
) {
// by using parent, we can infer the same font inheritance;
// you can also manually specify fonts or relevant classes/id with attributes if preferred/needed
attributes.style = 'position:absolute; left:-10000; font-size:1px;' + (attributes.style || "");
let testFontEl = createEl('p', attributes, string);
parent.appendChild(testFontEl);
let currentWidth = testFontEl.offsetWidth;
let workingFontSize = 1;
let i = 0;
while (currentWidth < maxWidth && i < 1000) {
testFontEl.style.fontSize = Number(testFontEl.style.fontSize.split("px")[0]) + 1 + "px";
currentWidth = testFontEl.offsetWidth;
if (currentWidth < maxWidth) {
workingFontSize = testFontEl.style.fontSize;
}
i++; // safety to prevent infinite loops
}
console.log("determined maximum font size:",workingFontSize,'one larger would produce',currentWidth,'max width allowed is',maxWidth,'parent is',parent);
parent.removeChild(testFontEl);
return workingFontSize.split("px")[0];
}
// utility function, though you could easily modify the function above to work without this.
// normally these have no default values specified, but adding them here
// to make usage clearer.
function createEl(tag="div", attrs={class:'some-class'}, children=[]) {
let el = document.createElement(tag);
if (attrs) {
Object.keys(attrs).forEach(attr => {
el.setAttribute(attr, attrs[attr])
})
}
if (children) {
children = Array.isArray(children) ? children : [children];
for (let child of children) {
if (typeof child === "number") child = ""+child;
if (typeof child === "string") {
el.insertAdjacentText("afterbegin", child);
}
else {
try {
el.appendChild(child)
} catch (e) {
debugger
}
}
}
}
return el;
};
use:
const getUsername = () => "MrHarry";
const username = getUsername();
const anchor = document.querySelector('.container');
const titleFontSize = findMaxFontSize(`Welcome, ${username}`, anchor, {style:'font-weight:900;'});
const titleFontStyle = `font-size:${titleFontSize}px;`;