Gibt es ein jQuery Autogrow Plugin für Textfelder?

68

Ich habe verschiedene Plugins zum automatischen Wachsen eines Textbereichs gefunden , aber keine Eingabetextfelder. Weiß jemand, ob es welche gibt?

Brad Gessler
quelle
Nur zur Verdeutlichung: Suchen Sie jemanden, bei dem das Feld immer größer wird, wenn der Text für das Textfeld zu groß wird, um den gesamten Text auf einmal anzuzeigen?
Paolo Bergantino

Antworten:

146

Hier ist ein Plugin, das genau das tut, wonach Sie suchen:

EDIT : Ich habe das Plugin gemäß Mathias 'Kommentar repariert. :) :)

Eine Demo finden Sie hier: http://jsfiddle.net/rRHzY

Das Plugin:

(function($){

    $.fn.autoGrowInput = function(o) {

        o = $.extend({
            maxWidth: 1000,
            minWidth: 0,
            comfortZone: 70
        }, o);

        this.filter('input:text').each(function(){

            var minWidth = o.minWidth || $(this).width(),
                val = '',
                input = $(this),
                testSubject = $('<tester/>').css({
                    position: 'absolute',
                    top: -9999,
                    left: -9999,
                    width: 'auto',
                    fontSize: input.css('fontSize'),
                    fontFamily: input.css('fontFamily'),
                    fontWeight: input.css('fontWeight'),
                    letterSpacing: input.css('letterSpacing'),
                    whiteSpace: 'nowrap'
                }),
                check = function() {

                    if (val === (val = input.val())) {return;}

                    // Enter new content into testSubject
                    var escaped = val.replace(/&/g, '&amp;').replace(/\s/g,'&nbsp;').replace(/</g, '&lt;').replace(/>/g, '&gt;');
                    testSubject.html(escaped);

                    // Calculate new width + whether to change
                    var testerWidth = testSubject.width(),
                        newWidth = (testerWidth + o.comfortZone) >= minWidth ? testerWidth + o.comfortZone : minWidth,
                        currentWidth = input.width(),
                        isValidWidthChange = (newWidth < currentWidth && newWidth >= minWidth)
                                             || (newWidth > minWidth && newWidth < o.maxWidth);

                    // Animate width
                    if (isValidWidthChange) {
                        input.width(newWidth);
                    }

                };

            testSubject.insertAfter(input);

            $(this).bind('keyup keydown blur update', check);

        });

        return this;

    };

})(jQuery);
James
quelle
2
Tolles Plugin, James! Ein Vorschlag: Vielleicht wäre es cool, wenn die EINGABEN auch beim Entfernen von Text kleiner würden.
Mathias Bynens
1
Danke Mathias; habe es gerade behoben - es sollte jetzt wie erwartet abnehmen :)
James
1
Perfekt! Du solltest das total bloggen.
Mathias Bynens
13
Großartig! Dies ist genau das, wonach ich gesucht habe. Sie sollten auf jeden Fall darüber bloggen und einen Link-Köder dazu bekommen, damit andere ihn in Google finden können.
Brad Gessler
1
böses Drehbuch, James! Ich weiß nicht, ob ich es verwenden werde, aber es ist schon eine Weile her, seit ich das letzte Mal die Freude gespürt habe, die schönes Javascript erzeugt!
Morten Bergfall
9

Ich habe ein jQuery-Plugin auf GitHub: https://github.com/MartinF/jQuery.Autosize.Input

Es verwendet den gleichen Ansatz wie James Antwort, hat jedoch einige der in den Kommentaren erwähnten Änderungen.

Ein Live-Beispiel finden Sie hier: http://jsfiddle.net/mJMpw/6/

Beispiel:

<input type="text" value="" placeholder="Autosize" data-autosize-input='{ "space": 40 }' />

input[type="data-autosize-input"] {
  width: 90px;
  min-width: 90px;
  max-width: 300px;
  transition: width 0.25s;    
}

Sie verwenden einfach CSS, um die minimale / maximale Breite festzulegen, und verwenden einen Übergang für die Breite, wenn Sie einen schönen Effekt erzielen möchten.

Sie können den Abstand / Abstand zum Ende als Wert in json-Notation für das Attribut data-autosize-input für das Eingabeelement angeben.

Natürlich können Sie es auch einfach mit jQuery initialisieren

$("selector").autosizeInput();
MartinF
quelle
7

Gutes Plugin, danke! Ich habe zwei Dinge geändert, die in meinem Projekt besser zu funktionieren schienen.

  1. Ich habe das TESTER-Tag in ein DIV geändert, um zu vermeiden, dass "Unerwarteter Aufruf der Methode oder des Eigenschaftenzugriffs" angezeigt wird. in IE8 (obwohl Ihre Demo in IE8 funktioniert. Gab es einen bestimmten Grund für die Verwendung eines benutzerdefinierten HTML-Tags?
  2. Nach der bind-Anweisung am Ende des Codes habe ich einen Aufruf von check () hinzugefügt, um die Größe des Textfelds unmittelbar nach dem Laden der Seite zu ändern, falls das Textfeld bereits beim Start Inhalt enthält.

Hoffe das hilft.

JP.
quelle
2
ging auch mit dem Scheck () am Ende
Stafford Williams
Wenn ich nach dem Laden der Seite die Überprüfungsfunktion ausführe, passiert nichts, aber onblur, onkeyup usw. funktioniert einwandfrei. Hat jemand eine Idee warum?
Kuboslav
4

Ich wollte nur eine kleine Verbesserung von James 'großartigem Plugin teilen. Fügen Sie diesen Code zur CSS-Deklaration für das Testerelement hinzu, um den Texteinzug zu berücksichtigen:

textIndent: 0

Ohne sie erbt das Testerelement in einigen Situationen möglicherweise versehentlich den Texteinzug von einer anderen Stelle, wodurch die Größe der Eingabe verringert wird.

Wie JP wollte auch ich die Eingabe von Anfang an auf die richtige Größe ändern, was ich nur geringfügig anders gemacht habe, indem ich "trigger ('keyup')" an den Methodenaufruf autoGrowInput gekettet habe, z.

$('#contact_form').autoGrowInput({comfortZone: 7, minWidth: 10, maxWidth: 200}).trigger('keyup');

Als Randnotiz habe ich mich auf dieser Website angemeldet, um James 'Lösung zu kommentieren, und ich bin etwas verärgert darüber, dass ich das nicht kann, weil ich nicht genug Reputationspunkte habe, um damit zu beginnen. Es tut mir leid, wenn ich etwas verpasst habe, aber das scheint zu bedeuten, dass ich dies posten muss. Dies ist ein Kommentar zur Hauptfrage und nicht angemessener zu James 'Lösung.

Michael
quelle
2

Ich hatte auch ersetzt

$(this).bind('keyup keydown blur update', check)

zu

$(this).bind('keyup blur update', check).bind('keydown', function() {
    setTimeout(check);
});

Damit wird die Größe des Felds direkt nach dem erneuten Rendern durch den Browser geändert. Es würde das Feld von einigem Geschwätz befreien.

Sergei Morozov
quelle
2

Ich habe ein Plugin für die Eingabe von Text erstellt, das dieses Verhalten neu erstellt. Es hat einige andere einzigartige Eigenschaften. Sie können ein Beispiel sehen und die Dokumentation des Plugins anzeigen . @james answer hat einige Probleme beim Einfügen von großem Text in die Eingabe. Um das Problem zu beheben, habe ich einige Änderungen an seinem Code vorgenommen. Hier ist eine Demo für dieses Beispiel.

(function($){        
    $.fn.autoGrowInput = function(o) {

        o = $.extend({
            maxWidth: 200,
            minWidth: 1,
            comfortZone: 1,
          width: 1
        }, o);

        this.filter('input:text').each(function(){

            var minWidth = o.minWidth || $(this).width(),
                maxWidth = o.maxWidth,
                val = '',
                input = $(this),
                testSubject = $('<tester/>').css({
                    position: 'absolute',
                    top: -9999,
                    left: -9999,
                    width: 'auto',
                    fontSize: input.css('fontSize'),
                    fontFamily: input.css('fontFamily'),
                    fontWeight: input.css('fontWeight'),
                    letterSpacing: input.css('letterSpacing'),
                    whiteSpace: 'nowrap'
                }),
                check = function() {

                    if (val === (val = input.val())) {return;}

                    // Enter new content into testSubject
                    var escaped = val.replace(/&/g, '&amp;').replace(/\s/g,'&nbsp;').replace(/</g, '&lt;').replace(/>/g, '&gt;');
                    testSubject.html(escaped);

                    // Calculate new width + whether to change
                    var testerWidth = testSubject.width(),
                    newWidth = testerWidth + o.comfortZone,
                    currentWidth = input.width();

                   if (testerWidth < minWidth) {
                       newWidth = minWidth;
                   } else if (testerWidth > maxWidth) {
                       newWidth = maxWidth;
                   } 

                   input.width(newWidth + o.comfortZone);  
            };

            testSubject.insertAfter(input);

            $(this).bind('input', check);

        });

        return this;

    };

})(jQuery);
Ajorquera
quelle
Das "Input" -Event ist großartig! Nur ein Hinweis: Das Ereignis funktioniert im IE nicht richtig: Das Löschen von Zeichen löst dieses Ereignis im IE9 nicht aus, und ältere Versionen haben es überhaupt nicht.
Simon Steinberger
0

Wenn Sie möchten, dass das Textfeld wächst, wenn sich die Zeichenfolge darin über seine Breite hinaus erstreckt, funktioniert dies möglicherweise für Sie ... Es erkennt das Größenattribut des Textfelds. Wenn die Länge der Zeichenfolge dieses Attribut überschreitet, wird das Textfeld beim Keyup auf die Länge der Zeichenfolge erweitert.

Im folgenden Skript ist "#test" eine Textfeld-ID.

<script language="javascript" type="text/javascript">
$(document).ready(function(){
    $("#test").keyup(function(){
        if($("#test").attr("size") < $("#test").val().length){
            size = $("#test").val().length;
            $("#test").attr("size",size);
        }
    })
});
</script>
BraedenP
quelle
1
Dies setzt voraus, dass der Text eine Schriftart mit fester Breite ist. Daher funktioniert es nicht mit Schriftarten wie Arial, Verdana usw.
James,
0

Komisch genug im IE-Überlauf: sichtbar wird sehr ernst genommen. Sie können diesen Effekt erzielen, indem Sie einen Überlauf anwenden: sichtbar auf Ihren Eingabeelementen. Ich bin mir nicht sicher, ob es ähnliche CSS-Tricks für moderne Browser gibt.

tbranyen
quelle
0

Ehrfürchtiges Plugin James! Vielen Dank. Ich habe den Check-Vorschlag am Ende von JP hinzugefügt, obwohl er sehr effektiv ist.

Außerdem habe ich einige Änderungen meinerseits hinzugefügt. Ich wollte die Größe für die Eingabe auf die maximale Größe einstellen, wenn die geänderte Breite die maximale Breite überschreitet, also fügte ich hinzu:

else if (widthexceeds){
    input.width(o.maxWidth);
}

unterhalb der if-Prüfung auf isValidWidthChange wo widthexceeds = newWidth > o.maxWidth

Snigdha Batra
quelle
0

Ich habe ein Plugin erstellt input-autogrow, um dieses Problem für meine eigenen Projekte zu lösen. Dieses Plugin basiert ursprünglich auf der Antwort von James, wurde jedoch in vielerlei Hinsicht verbessert.

https://github.com/westonganger/input-autogrow

input-autogrowist ein Plugin für automatisch wachsende Eingänge. Dieses Plugin unterscheidet sich von anderen, da diese Bibliothek in der Regel auf Textbereich-Tags abzielt und stattdessen auf Eingabe-Tags ausgerichtet ist. Benötigt eine DOM-Bibliothek wie jQuery, Zepto oder eine andere, die $ .fn-Plugins unterstützt.

Hier sind einige Anwendungsbeispiele.

/* Makes elements readonly if they already have the readonly attribute */
$('input.autogrow').inputAutogrow();

/* Manually trigger update */
$('input.autogrow').trigger('autogrow');
/* or */
$('input.autogrow').trigger('change');

/* Custom Options */
$('input.autogrow').inputAutogrow({maxWidth: 500, minWidth: 25, trailingSpace: 10});

/* Remove autogrow from input */
$('input.autogrow').inputAutogrow('destroy');
Weston Ganger
quelle