我需要将用户输入的文本显示为固定大小的div.我想要的是自动调整字体大小,以便文本尽可能填充框.
所以 - 如果div是400px x 300px.如果有人输入ABC,那么它真的很大.如果他们输入一个段落,那么它将是一个很小的字体.
我可能想要从最大字体大小开始 - 可能是32px,虽然文本太大而不适合容器,但缩小字体大小直到它适合.
Gee*_*key 164
谢谢攻击.我想使用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 });
});
Run Code Online (Sandbox Code Playgroud)
我的HTML是这样的
<div class='jtextfill' style='width:100px;height:50px;'>
<span>My Text Here</span>
</div>
Run Code Online (Sandbox Code Playgroud)
这是我的第一个jquery插件,所以它可能没有它应该的那么好.指针当然是受欢迎的.
mek*_*all 52
我没有发现任何以前的解决方案由于性能不佳而足够,所以我自己创建了使用简单的数学而不是循环.应该在所有浏览器中都能正常工作.
根据这个性能测试案例,它比这里找到的其他解决方案快得多.
(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);
Run Code Online (Sandbox Code Playgroud)
att*_*ack 33
尽管我喜欢这个答案的偶尔的赞成(谢谢!),但这并不是解决这个问题的最佳方法.请在这里查看一些其他精彩的答案,特别是那些找到没有循环的解决方案的答案.
不过,为了便于参考,这是我原来的答案:
<html>
<head>
<style type="text/css">
#dynamicDiv
{
background: #CCCCCC;
width: 300px;
height: 100px;
font-size: 64px;
overflow: hidden;
}
</style>
<script type="text/javascript">
function shrink()
{
var textSpan = document.getElementById("dynamicSpan");
var textDiv = document.getElementById("dynamicDiv");
textSpan.style.fontSize = 64;
while(textSpan.offsetHeight > textDiv.offsetHeight)
{
textSpan.style.fontSize = parseInt(textSpan.style.fontSize) - 1;
}
}
</script>
</head>
<body onload="shrink()">
<div id="dynamicDiv"><span id="dynamicSpan">DYNAMIC FONT</span></div>
</body>
</html>
Run Code Online (Sandbox Code Playgroud)
这是一个有类的版本:
<html>
<head>
<style type="text/css">
.dynamicDiv
{
background: #CCCCCC;
width: 300px;
height: 100px;
font-size: 64px;
overflow: hidden;
}
</style>
<script type="text/javascript">
function shrink()
{
var textDivs = document.getElementsByClassName("dynamicDiv");
var textDivsLength = textDivs.length;
// Loop through all of the dynamic divs on the page
for(var i=0; i<textDivsLength; i++) {
var textDiv = textDivs[i];
// Loop through all of the dynamic spans within the div
var textSpan = textDiv.getElementsByClassName("dynamicSpan")[0];
// Use the same looping logic as before
textSpan.style.fontSize = 64;
while(textSpan.offsetHeight > textDiv.offsetHeight)
{
textSpan.style.fontSize = parseInt(textSpan.style.fontSize) - 1;
}
}
}
</script>
</head>
<body onload="shrink()">
<div class="dynamicDiv"><span class="dynamicSpan">DYNAMIC FONT</span></div>
<div class="dynamicDiv"><span class="dynamicSpan">ANOTHER DYNAMIC FONT</span></div>
<div class="dynamicDiv"><span class="dynamicSpan">AND YET ANOTHER DYNAMIC FONT</span></div>
</body>
</html>
Run Code Online (Sandbox Code Playgroud)
Hof*_*ann 32
大多数其他答案都使用循环来减小字体大小,直到它适合div为止,这非常慢,因为每次字体更改大小时页面都需要重新渲染元素.我最终不得不编写自己的算法,使其以允许我定期更新其内容而不冻结用户浏览器的方式执行.我添加了一些其他功能(旋转文本,添加填充)并将其打包为jQuery插件,您可以在以下位置获取:
https://github.com/DanielHoffmann/jquery-bigtext
简单地打电话
$("#text").bigText();
Run Code Online (Sandbox Code Playgroud)
它很适合你的容器.
在这里看到它:
http://danielhoffmann.github.io/jquery-bigtext/
目前它有一些限制,div必须具有固定的高度和宽度,并且它不支持将文本包装成多行.
我将努力获得一个选项来设置最大字体大小.
编辑:我发现插件有一些问题,它除了标准版之外它不处理其他框模型而且div不能有边距或边框.我会努力的.
Edit2:我现在已经解决了这些问题和限制,并添加了更多选项.您可以设置最大字体大小,也可以选择使用宽度,高度或两者来限制字体大小.我将努力接受包装器元素中的max-width和max-height值.
Edit3:我已将插件更新到1.2.0版.代码和新选项(verticalAlign,horizontalAlign,textAlign)的主要清理以及对span标记内部元素的支持(如换行符或字体很棒的图标).
这是基于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);
Run Code Online (Sandbox Code Playgroud)
这是一个改进的循环方法,它使用二进制搜索以尽可能少的步骤找到适合父级的最大可能大小(这比步进固定字体大小更快,更准确).代码也以多种方式优化以提高性能.
默认情况下,将执行10个二进制搜索步骤,这将达到最佳大小的0.1%.您可以将numIter设置为某个值N,以获得最佳大小的1/2 ^ N.
使用CSS选择器调用它,例如: fitToParent('.title-span');
/**
* Fit all elements matching a given CSS selector to their parent elements'
* width and height, by adjusting the font-size attribute to be as large as
* possible. Uses binary search.
*/
var fitToParent = function(selector) {
var numIter = 10; // Number of binary search iterations
var regexp = /\d+(\.\d+)?/;
var fontSize = function(elem) {
var match = elem.css('font-size').match(regexp);
var size = match == null ? 16 : parseFloat(match[0]);
return isNaN(size) ? 16 : size;
}
$(selector).each(function() {
var elem = $(this);
var parentWidth = elem.parent().width();
var parentHeight = elem.parent().height();
if (elem.width() > parentWidth || elem.height() > parentHeight) {
var maxSize = fontSize(elem), minSize = 0.1;
for (var i = 0; i < numIter; i++) {
var currSize = (minSize + maxSize) / 2;
elem.css('font-size', currSize);
if (elem.width() > parentWidth || elem.height() > parentHeight) {
maxSize = currSize;
} else {
minSize = currSize;
}
}
elem.css('font-size', minSize);
}
});
};
Run Code Online (Sandbox Code Playgroud)
我已经为AngularJS创建了一个指令 - 受到GeekyMonkey的回答的启发,但没有jQuery依赖.
演示: http ://plnkr.co/edit/8tPCZIjvO3VSApSeTtYr?p =preview
标记
<div class="fittext" max-font-size="50" text="Your text goes here..."></div>
指示
app.directive('fittext', function() {
return {
scope: {
minFontSize: '@',
maxFontSize: '@',
text: '='
},
restrict: 'C',
transclude: true,
template: '<div ng-transclude class="textContainer" ng-bind="text"></div>',
controller: function($scope, $element, $attrs) {
var fontSize = $scope.maxFontSize || 50;
var minFontSize = $scope.minFontSize || 8;
// text container
var textContainer = $element[0].querySelector('.textContainer');
angular.element(textContainer).css('word-wrap', 'break-word');
// max dimensions for text container
var maxHeight = $element[0].offsetHeight;
var maxWidth = $element[0].offsetWidth;
var textContainerHeight;
var textContainerWidth;
var resizeText = function(){
do {
// set new font size and determine resulting dimensions
textContainer.style.fontSize = fontSize + 'px';
textContainerHeight = textContainer.offsetHeight;
textContainerWidth = textContainer.offsetWidth;
// shrink font size
var ratioHeight = Math.floor(textContainerHeight / maxHeight);
var ratioWidth = Math.floor(textContainerWidth / maxWidth);
var shrinkFactor = ratioHeight > ratioWidth ? ratioHeight : ratioWidth;
fontSize -= shrinkFactor;
} while ((textContainerHeight > maxHeight || textContainerWidth > maxWidth) && fontSize > minFontSize);
};
// watch for changes to text
$scope.$watch('text', function(newText, oldText){
if(newText === undefined) return;
// text was deleted
if(oldText !== undefined && newText.length < oldText.length){
fontSize = $scope.maxFontSize;
}
resizeText();
});
}
};
});
Run Code Online (Sandbox Code Playgroud)
我从Marcus Ekwall上面分享了上面的脚本:https://gist.github.com/3945316并根据我的喜好调整它,它现在在窗口调整大小时触发,这样孩子总是适合它的容器.我已粘贴下面的脚本作为参考.
(function($) {
$.fn.textfill = function(maxFontSize) {
maxFontSize = parseInt(maxFontSize, 10);
return this.each(function(){
var ourText = $("span", this);
function resizefont(){
var parent = ourText.parent(),
maxHeight = parent.height(),
maxWidth = parent.width(),
fontSize = parseInt(ourText.css("fontSize"), 10),
multiplier = maxWidth/ourText.width(),
newSize = (fontSize*(multiplier));
ourText.css("fontSize", maxFontSize > 0 && newSize > maxFontSize ? maxFontSize : newSize );
}
$(window).resize(function(){
resizefont();
});
resizefont();
});
};
})(jQuery);
Run Code Online (Sandbox Code Playgroud)
这是我对OP答案的修改。
简而言之,许多尝试优化此功能的人都抱怨正在使用循环。是的,尽管循环可能很慢,但其他方法可能不准确。
因此,我的方法使用二进制搜索来找到最佳字体大小:
$.fn.textfill = function()
{
var self = $(this);
var parent = self.parent();
var attr = self.attr('max-font-size');
var maxFontSize = parseInt(attr, 10);
var unit = attr.replace(maxFontSize, "");
var minFontSize = parseInt(self.attr('min-font-size').replace(unit, ""));
var fontSize = (maxFontSize + minFontSize) / 2;
var maxHeight = parent.height();
var maxWidth = parent.width();
var textHeight;
var textWidth;
do
{
self.css('font-size', fontSize + unit);
textHeight = self.height();
textWidth = self.width();
if(textHeight > maxHeight || textWidth > maxWidth)
{
maxFontSize = fontSize;
fontSize = Math.floor((fontSize + minFontSize) / 2);
}
else if(textHeight < maxHeight || textWidth < maxWidth)
{
minFontSize = fontSize;
fontSize = Math.floor((fontSize + maxFontSize) / 2);
}
else
break;
}
while(maxFontSize - minFontSize > 1 && maxFontSize > minFontSize);
self.css('font-size', fontSize + unit);
return this;
}
function resizeText()
{
$(".textfill").textfill();
}
$(document).ready(resizeText);
$(window).resize(resizeText);
Run Code Online (Sandbox Code Playgroud)
这也允许元素指定最小和最大字体:
<div class="container">
<div class="textfill" min-font-size="10px" max-font-size="72px">
Text that will fill the container, to the best of its abilities, and it will <i>never</i> have overflow.
</div>
</div>
Run Code Online (Sandbox Code Playgroud)
此外,该算法是无单位的。您可以指定em
,rem
,%
等,它将使用它的最终结果。
这是小提琴:https : //jsfiddle.net/fkhqhnqe/1/
归档时间: |
|
查看次数: |
258743 次 |
最近记录: |