我需要显示用户输入的文本到一个固定大小的div。我想要的是字体大小自动调整,以便文本尽可能多地填充框。
如果div是400px x 300px。如果有人输入ABC,那么字体就很大。如果他们输入一个段落,那么它将是一个很小的字体。
我可能想要从最大字体大小开始——可能是32px,当文本太大而不适合容器时,缩小字体大小直到它适合。
我需要显示用户输入的文本到一个固定大小的div。我想要的是字体大小自动调整,以便文本尽可能多地填充框。
如果div是400px x 300px。如果有人输入ABC,那么字体就很大。如果他们输入一个段落,那么它将是一个很小的字体。
我可能想要从最大字体大小开始——可能是32px,当文本太大而不适合容器时,缩小字体大小直到它适合。
当前回答
编辑:此代码用于在HTML5视频的顶部显示注释。当视频调整大小时(当浏览器窗口调整大小时),它会动态地改变字体大小。注释被连接到视频(就像YouTube上的注释一样),这就是代码使用实例而不是直接使用DOM句柄的原因。
根据请求,我将抛出一些代码,我用来实现这一点。(HTML5视频上方的文本框。)代码是很久以前写的,坦率地说,我认为它相当混乱。因为这个问题已经被回答了,而且答案在很久以前就已经被接受了,所以我就不麻烦重写了。但是如果有人想把这个简化一点,欢迎你!
// Figure out the text size:
var text = val['text'];
var letters = text.length;
var findMultiplier = function(x) { // g(x)
/* By analysing some functions with regression, the resulting function that
gives the best font size with respect to the number of letters and the size
of the note is:
g(x) = 8.3 - 2.75x^0.15 [1 < x < 255]
f(x) = g(letters) * (x / 1000)^0.5
Font size = f(size)
*/
return 8.3 - 2.75 * Math.pow(x, 0.15);
};
var findFontSize = function(x) { // f(x)
return findMultiplier(letters) * Math.pow(x / 1000, 0.5);
};
val.setFontSizeListener = function() {
p.style.fontSize = '1px'; // So the text should not overflow the box when measuring.
var noteStyle = window.getComputedStyle(table);
var width = noteStyle.getPropertyValue('width');
var height = noteStyle.getPropertyValue('height');
var size = width.substring(0, width.length - 2) * height.substring(0, height.length - 2);
p.style.fontSize = findFontSize(size) + 'px';
};
window.addEventListener('resize', val.setFontSizeListener);
您可能需要将这些数字从font-family调整为font-family。一个很好的方法就是下载一个叫做GeoGebra的免费图形可视化工具。更改文本的长度和框的大小。然后手动设置大小。将手工结果绘制到坐标系统中。然后输入我在这里发布的两个方程,然后调整数字,直到“我的”图形符合你自己手动绘制的点。
其他回答
这是基于GeekyMonkey上面发布的内容,并进行了一些修改。
; (function($) {
/**
* Resize inner element to fit the outer element
* @author Some modifications by Sandstrom
* @author Code based on earlier works by Russ Painter (WebDesign@GeekyMonkey.com)
* @version 0.2
*/
$.fn.textfill = function(options) {
options = jQuery.extend({
maxFontSize: null,
minFontSize: 8,
step: 1
}, options);
return this.each(function() {
var innerElements = $(this).children(':visible'),
fontSize = options.maxFontSize || innerElements.css("font-size"), // use current font-size by default
maxHeight = $(this).height(),
maxWidth = $(this).width(),
innerHeight,
innerWidth;
do {
innerElements.css('font-size', fontSize);
// use the combined height of all children, eg. multiple <p> elements.
innerHeight = $.map(innerElements, function(e) {
return $(e).outerHeight();
}).reduce(function(p, c) {
return p + c;
}, 0);
innerWidth = innerElements.outerWidth(); // assumes that all inner elements have the same width
fontSize = fontSize - options.step;
} while ((innerHeight > maxHeight || innerWidth > maxWidth) && fontSize > options.minFontSize);
});
};
})(jQuery);
这是我最后得到的结果:
这是该插件的链接:https://plugins.jquery.com/textfill/ 还有一个来源的链接:http://jquery-textfill.github.io/
;(function($) {
$.fn.textfill = function(options) {
var fontSize = options.maxFontPixels;
var ourText = $('span:visible:first', this);
var maxHeight = $(this).height();
var maxWidth = $(this).width();
var textHeight;
var textWidth;
do {
ourText.css('font-size', fontSize);
textHeight = ourText.height();
textWidth = ourText.width();
fontSize = fontSize - 1;
} while ((textHeight > maxHeight || textWidth > maxWidth) && fontSize > 3);
return this;
}
})(jQuery);
$(document).ready(function() {
$('.jtextfill').textfill({ maxFontPixels: 36 });
});
我的HTML是这样的
<div class='jtextfill' style='width:100px;height:50px;'>
<span>My Text Here</span>
</div>
大多数其他答案使用循环来减少字体大小,直到它适合div,这是非常缓慢的,因为页面需要重新渲染元素每次字体改变大小。我最终不得不编写自己的算法,使它能够定期更新内容,而不会冻结用户浏览器。我添加了一些其他功能(旋转文本,添加填充),并将其打包为jQuery插件,你可以在:
https://github.com/DanielHoffmann/jquery-bigtext
简单的电话
$("#text").bigText();
它会非常适合你的容器。
在这里看到它的行动:
http://danielhoffmann.github.io/jquery-bigtext/
现在它有一些限制,div必须有固定的高度和宽度,它不支持将文本包装成多行。
我将努力获得一个选项来设置最大字体大小。
编辑:我发现了更多的问题与插件,它不处理其他盒子模型除了标准的和div不能有边缘或边界。我会努力的。
Edit2:我现在已经修复了这些问题和限制,并添加了更多选项。你可以设置最大字体大小,你也可以选择限制字体大小使用宽度,高度或两者。我将在包装器元素中接受max-width和max-height值。
Edit3:我已经将插件更新到1.2.0版本。对代码和新选项(verticalAlign, horizontalAlign, textAlign)进行了重大清理,并支持span标签内的内部元素(如换行或字体很棒的图标)。
它使用二分搜索,进行10次迭代。最简单的方法是执行while循环,并将字体大小增加1,直到元素开始溢出。可以使用element来确定元素何时开始溢出。offsetHeight和element.scrollHeight。如果scrollHeight大于offsetHeight,则字体大小过大。
二分搜索是一个更好的算法。它还受到希望执行的迭代次数的限制。只需调用flexFont并插入div id,它将在8px到96px之间调整字体大小。
我花了一些时间研究这个主题,并尝试了不同的库,但最终我认为这是最简单、最直接的解决方案。
注意,如果你愿意,你可以更改使用offsetWidth和scrollWidth,或者将两者都添加到这个函数中。
// Set the font size using overflow property and div height
function flexFont(divId) {
var content = document.getElementById(divId);
content.style.fontSize = determineMaxFontSize(content, 8, 96, 10, 0) + "px";
};
// Use binary search to determine font size
function determineMaxFontSize(content, min, max, iterations, lastSizeNotTooBig) {
if (iterations === 0) {
return lastSizeNotTooBig;
}
var obj = fontSizeTooBig(content, min, lastSizeNotTooBig);
// if `min` too big {....min.....max.....}
// search between (avg(min, lastSizeTooSmall)), min)
// if `min` too small, search between (avg(min,max), max)
// keep track of iterations, and the last font size that was not too big
if (obj.tooBig) {
(lastSizeTooSmall === -1) ?
determineMaxFontSize(content, min / 2, min, iterations - 1, obj.lastSizeNotTooBig, lastSizeTooSmall) :
determineMaxFontSize(content, (min + lastSizeTooSmall) / 2, min, iterations - 1, obj.lastSizeNotTooBig, lastSizeTooSmall);
} else {
determineMaxFontSize(content, (min + max) / 2, max, iterations - 1, obj.lastSizeNotTooBig, min);
}
}
// determine if fontSize is too big based on scrollHeight and offsetHeight,
// keep track of last value that did not overflow
function fontSizeTooBig(content, fontSize, lastSizeNotTooBig) {
content.style.fontSize = fontSize + "px";
var tooBig = content.scrollHeight > content.offsetHeight;
return {
tooBig: tooBig,
lastSizeNotTooBig: tooBig ? lastSizeNotTooBig : fontSize
};
}
我没有发现任何以前的解决方案是足够的,由于糟糕的性能,所以我自己使用简单的数学,而不是循环。在所有浏览器中都可以正常工作。
根据这个性能测试用例,它比这里找到的其他解决方案快得多。
(function($) {
$.fn.textfill = function(maxFontSize) {
maxFontSize = parseInt(maxFontSize, 10);
return this.each(function(){
var ourText = $("span", this),
parent = ourText.parent(),
maxHeight = parent.height(),
maxWidth = parent.width(),
fontSize = parseInt(ourText.css("fontSize"), 10),
multiplier = maxWidth/ourText.width(),
newSize = (fontSize*(multiplier-0.1));
ourText.css(
"fontSize",
(maxFontSize > 0 && newSize > maxFontSize) ?
maxFontSize :
newSize
);
});
};
})(jQuery);
如果你想投稿,我已经把这个添加到Gist。