【问题标题】:Shrinking font-size at a user types to fit in an input using Javascript缩小用户类型的字体大小以适应使用 Javascript 的输入
【发布时间】:2011-09-01 03:22:18
【问题描述】:

Apple 的 MobileMe 使用 Javascript 在用户键入时更改其主页上电子邮件登录的字体大小,以便文本始终适合可用空间而不会溢出滚动。

虽然我可以看到如何在每次按键时执行一个功能,但我很好奇如何每次计算字体大小以使其始终适合输入字段。有没有办法用可变宽度字体测量一段文本的长度?他们是如何实现这种效果的?

试试看我的意思: http://www.me.com/

【问题讨论】:

标签: javascript input dom-events user-input font-size


【解决方案1】:

我从其他答案的大杂烩中制作了另一个。我认为这提供了最简单的单属性更改解决方案。

它可能过于冗长,或者可以在某些方面进行重构以使其清晰,欢迎提出任何建议!

$(document).ready(function(){

    // get the current styles size, in px integer.
    var maxSize = parseInt($('.fields').css("font-size"));

    function isOverflowed (element){

        if ( $(element)[0].scrollWidth > $(element).innerWidth() ) {
            return true;
        } else {
            return false;
        }
    };

    function decreaseSize (element){

        var fontSize = parseInt($(element).css("font-size"));
        fontSize = fontSize - 1 + "px";
        $(element).css({'font-size':fontSize});

    }

    function maximizeSize (element){

        var fontSize = parseInt($(element).css("font-size"));
        while (!isOverflowed(element) && fontSize < maxSize){
            fontSize = fontSize + 1 + "px";
            $(element).css({'font-size':fontSize});

            // if this loop increases beyond the width, decrease again. 
            // hacky.
            if (isOverflowed(element)){
                while (isOverflowed(element)) {
                    decreaseSize(element);
                }            
            }     

        }        

    }

    function fixSize (element){
        if (isOverflowed(element)){
            while (isOverflowed(element)) {
                decreaseSize(element);
            }            
        } else {
            maximizeSize(element);
        }
    }

    // execute it onready.
    $('.fields').each(function(){
        fixSize(this);
    });

    // bind to it.
    $(function() {
        $('.fields').keyup(function() {
            fixSize(this);
        })
    });    

});

【讨论】:

  • 这看起来/感觉像是一个更优雅的解决方案。我在这里创建了一个 JSFiddle:jsfiddle.net/dsuv8onp
  • 此外,如果您想将其默认应用于所有文本字段,则可以使用 $('input[type=text]') 而不是 .fields。
【解决方案2】:

我过去曾使用 jQuery 完成此操作。您可以像这样测量一段文本的大小:

// txt is the text to measure, font is the full CSS font declaration,
// e.g. "bold 12px Verdana"
function measureText(txt, font) {
    var id = 'text-width-tester',
        $tag = $('#' + id);
    if (!$tag.length) {
        $tag = $('<span id="' + id + '" style="display:none;font:' + font + ';">' + txt + '</span>');
        $('body').append($tag);
    } else {
        $tag.css({font:font}).html(txt);
    }
    return {
        width: $tag.width(),
        height: $tag.height()
    }
}

var size = measureText("spam", "bold 12px Verdana");
console.log(size.width + ' x ' + size.height); // 35 x 12.6

为了适应给定的空间,它有点棘手 - 您需要分离出 font-size 声明并适当地缩放它。根据您的工作方式,如果您分解font 声明的不同部分,这可能是最简单的。调整大小函数可能看起来像这样(同样,很明显,这是依赖于 jQuery 的):

function shrinkToFill(input, fontSize, fontWeight, fontFamily) {
    var $input = $(input),
        txt = $input.val(),
        maxWidth = $input.width() + 5, // add some padding
        font = fontWeight + " " + fontSize + "px " + fontFamily;
    // see how big the text is at the default size
    var textWidth = measureText(txt, font).width;
    if (textWidth > maxWidth) {
        // if it's too big, calculate a new font size
        // the extra .9 here makes up for some over-measures
        fontSize = fontSize * maxWidth / textWidth * .9;
        font = fontWeight + " " + fontSize + "px " + fontFamily;
        // and set the style on the input
        $input.css({font:font});
    } else {
        // in case the font size has been set small and 
        // the text was then deleted
        $input.css({font:font});
}

你可以在这里看到这个:http://jsfiddle.net/nrabinowitz/9BFQ8/5/

测试似乎表明这有点令人不安,至少在 Google Chrome 中是这样,因为只使用了全整数字体大小。您可能可以使用基于em 的字体声明做得更好,尽管这可能有点棘手 - 您需要确保文本宽度测试器的1em 大小与输入的大小相同.

【讨论】:

  • 真的,完全不喜欢一个功能齐全且相对清晰的例子来说明你感兴趣的东西吗?
  • 不,根本不是这样。非常感谢。我陷入了法律问题(公司注册、商标、ToS 和 PP),两天内我还没有进入 SO。很抱歉延迟投票并将其标记为已回答。
  • 谢谢!对不起,如果我脾气暴躁 - 感谢您的考虑。
  • 呵呵。 np。再次感谢您帮助我。这是一个非常好的效果。
  • 很棒的功能!我做了类似的东西,但没有那么整洁。 +1。
猜你喜欢
  • 1970-01-01
  • 2016-06-01
  • 2018-10-02
  • 1970-01-01
  • 2014-04-18
  • 2021-11-11
  • 2012-12-06
  • 2018-04-21
  • 1970-01-01
相关资源
最近更新 更多