10 Stimmen

Verkleinern der Schriftgröße bei der Eingabe eines Benutzers mit Javascript

MobileMe von Apple verwendet Javascript, um die Schriftgröße bei der E-Mail-Anmeldung auf der Homepage während der Eingabe zu ändern, so dass der Text immer in den verfügbaren Platz passt, ohne dass ein Überlauf entsteht.

Ich kann zwar sehen, wie man bei jedem Tastendruck eine Funktion ausführt, aber ich bin neugierig, wie man die Schriftgröße jedes Mal berechnet, damit sie immer in das Eingabefeld passt. Gibt es eine Möglichkeit, die Länge eines Textstücks mit einer Schriftart mit variabler Breite zu messen? Wie wird dieser Effekt erreicht?

Probieren Sie es aus, um zu sehen, was ich meine: http://www.me.com/

28voto

nrabinowitz Punkte 54138

Ich habe dies in der Vergangenheit mit jQuery getan. Sie können die Größe eines Textstücks wie folgt messen:

// 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

Um dies in einen gegebenen Raum einzupassen, ist es ein wenig kniffliger - Sie müssen die font-size Erklärung und skalieren Sie sie entsprechend. Je nachdem, wie Sie vorgehen, ist es vielleicht am einfachsten, wenn Sie die verschiedenen Teile der font Erklärung. Eine Größenänderungsfunktion könnte wie folgt aussehen (auch dies ist natürlich jQuery-abhängig):

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

Sie können dies hier in Aktion sehen: http://jsfiddle.net/nrabinowitz/9BFQ8/5/

Tests scheinen zu zeigen, dass dies ein wenig ruckelig ist, zumindest in Google Chrome, da nur ganzzahlige Schriftgrößen verwendet werden. Möglicherweise können Sie es besser machen mit einer em -basierte Schriftartendeklaration, obwohl dies ein wenig knifflig sein könnte - Sie müssten sicherstellen, dass die 1em Die Größe für den Textbreitentester ist die gleiche wie für die Eingabe.

2voto

Ben Punkte 159

Ich habe eine weitere Antwort aus einem Sammelsurium anderer Antworten erstellt. Ich denke, dies ist die einfachste Lösung mit nur einer Eigenschaftsänderung.

Es ist wahrscheinlich zu ausführlich oder könnte in mancher Hinsicht überarbeitet werden, um mehr Klarheit zu schaffen - Vorschläge sind willkommen!

$(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);
        })
    });    

});

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X