当前位置:  开发笔记 > 编程语言 > 正文

自动调整动态文本以填充固定大小的容器

如何解决《自动调整动态文本以填充固定大小的容器》经验,为你挑选了9个好方法。

我需要将用户输入的文本显示为固定大小的div.我想要的是自动调整字体大小,以便文本尽可能填充框.

所以 - 如果div是400px x 300px.如果有人输入ABC,那么它真的很大.如果他们输入一个段落,那么它将是一个很小的字体.

我可能想要从最大字体大小开始 - 可能是32px,虽然文本太大而不适合容器,但缩小字体大小直到它适合.



1> GeekyMonkey..:

谢谢攻击.我想使用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是这样的

My Text Here

这是我的第一个jquery插件,所以它可能没有它应该的那么好.指针当然是受欢迎的.


我实际上只是清理它并将其打包为jquery.com提供的插件,网址为http://plugins.jquery.com/project/TextFill
这种方法非常慢,每次字体更改大小时都需要重新呈现元素.检查我的答案,以获得更好的方法.
@GeekyMonkey,你拉了插件吗?只是跟着这个页面的欺骗链接,并认为我看看,但jQuery.com链接到您的网站返回'404`.

2> mekwall..:

我没有发现任何以前的解决方案由于性能不佳而足够,所以我自己创建了使用简单的数学而不是循环.应该在所有浏览器中都能正常工作.

根据这个性能测试案例,它比这里找到的其他解决方案快得多.

(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.


@Jon,我在多行文本填充方面玩了一点,最后得到了[此解决方案](http://jsfiddle.net/mekwall/fNyHs/).沙尘暴的方法很可能更准确,但这个更快;)
这是一个具有最小字体大小和最大值的版本:https://gist.github.com/1714284

3> attack..:

尽管我喜欢这个答案的偶尔的赞成(谢谢!),但这并不是解决这个问题的最佳方法.请在这里查看一些其他精彩的答案,特别是那些找到没有循环的解决方案的答案.


不过,为了便于参考,这是我原来的答案:









    
DYNAMIC FONT

这是一个有的版本:









    
DYNAMIC FONT
ANOTHER DYNAMIC FONT
AND YET ANOTHER DYNAMIC FONT


我发现这对`offsetWidth`效果更好,我还必须为size创建一个变量然后追加px`textSpan.style.fontSize = size +"px";`
确定'+'px"'是必要的.

4> Hoffmann..:

大多数其他答案都使用循环来减小字体大小,直到它适合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,horizo​​ntalAlign,textAlign)的主要清理以及对span标记内部元素的支持(如换行符或字体很棒的图标).



5> sandstrom..:

这是基于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 

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);


这很棒,但我该如何使用它?我做$('.outer').textfill(); 我没有改变.
谢谢,这是一个非常好的实现.有一件事我遇到了:如果你正在处理很长的文本字符串和很窄的容器,文本字符串会伸出容器,但如果它不outerWidth仍将被计算.抛出"自动换行:破词;" 进入你的容器的CSS,它将解决这个问题.

6> Luke Hutchis..:

这是一个改进的循环方法,它使用二进制搜索以尽可能少的步骤找到适合父级的最大可能大小(这比步进固定字体大小更快,更准确).代码也以多种方式优化以提高性能.

默认情况下,将执行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);
        }
    });
};



7> sqren..:

我已经为AngularJS创建了一个指令 - 受到GeekyMonkey的回答的启发,但没有jQuery依赖.

演示: http ://plnkr.co/edit/8tPCZIjvO3VSApSeTtYr?p =preview

标记

指示

app.directive('fittext', function() {

  return {
    scope: {
      minFontSize: '@',
      maxFontSize: '@',
      text: '='
    },
    restrict: 'C',
    transclude: true,
    template: '
', 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(); }); } }; });



8> nimrod..:

我从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);


你试图帮助提问者真是太好了.但是,在某些情况下,仅使用链接留下答案可能会有害.虽然你的答案现在很好,但如果链接永远消失,你的答案就会失去它的价值.因此,如果您在答案中总结文章中的内容,将会很有帮助.请参阅[this](http://goo.gl/wQTjc)问题以获得澄清.

9> Boom..:

这是我对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);

这也允许元素指定最小和最大字体:

Text that will fill the container, to the best of its abilities, and it will never have overflow.

此外,该算法是无单位的。您可以指定emrem%等,它将使用它的最终结果。

这是小提琴:https : //jsfiddle.net/fkhqhnqe/1/

推荐阅读
爱唱歌的郭少文_
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有