HTML-Texteingabefeld während der Eingabe wachsen lassen?

80

Ich kann die anfängliche Texteingabegröße in CSS wie folgt einstellen:

width: 50px;

Aber ich möchte, dass es wächst, wenn ich tippe, bis es zum Beispiel 200px erreicht. Kann dies in reinem CSS, HTML, vorzugsweise ohne Javascript erfolgen?

Veröffentlichen Sie natürlich auch Ihre js / jquery-Lösungen, aber wenn dies ohne sie möglich ist, ist das großartig.

Mein Versuch hier:

http://jsfiddle.net/jszjz/2/

Stann
quelle
Ich denke, diese SO-Frage wird Ihnen helfen: stackoverflow.com/questions/1288297/…
Curt
Für die Aufzeichnung war ich nicht. Scheint eine gültige Frage zu sein, wenn auch ähnlich der, die ich verlinkt habe.
Curt
Andre: Versuchen Sie bitte, die Kommentare konstruktiv zu halten.
Seth
1
Sie können einen Absatz mit contenteditable verwenden. Das wird erweitert, wenn Sie alleine tippen.
Costa

Antworten:

105

Hier ist ein Beispiel, bei dem nur CSS und Inhalte bearbeitet werden können :

jsFiddle Beispiel

CSS

span 
{
    border: solid 1px black;
}
div 
{
    max-width: 200px;   
}

HTML

<div>
    <span contenteditable="true">sdfsd</span>
</div>
Joe
quelle
4
YAY. Ich habe es gerade in IE6-9, den neuesten Versionen von Opera, Firefox und Chrome versucht - und OMG - es hat überall funktioniert!
Stann
4
Für mich in Chrome erweitert dies das Element um eine Reihe, wenn es die maximale Breite erreicht. Es funktioniert auch nicht, wenn die Eingabe Teil eines Formulars sein soll.
Paul
5
Ersetzen Sie für ein mehrzeiliges Eingabefeld (benutzerdefinierte Zeilenumbrüche) spandurch div. Beachten Sie, dass word-wrap: break-worddies erforderlich ist oder dass Wörter länger sind als max-widthdas Div-Feld überläuft
CodeManX
6
Stellen Sie sicher, dass Sie nach unerwünschtem HTML-Code suchen, der durch Kopieren und Einfügen in den inhaltsbearbeitbaren Bereich gelangen kann.
Brian Peacock
3
Wird dies mit Formular gesendet?
Tomáš Zato - Wiedereinsetzung Monica
38

Ich habe das gerade für dich geschrieben, ich hoffe es gefällt dir :) Keine Garantie, dass es browserübergreifend ist, aber ich denke es ist :)

(function(){
    var min = 100, max = 300, pad_right = 5, input = document.getElementById('adjinput');

    input.style.width = min+'px';
    input.onkeypress = input.onkeydown = input.onkeyup = function(){
        var input = this;
        setTimeout(function(){
            var tmp = document.createElement('div');
            tmp.style.padding = '0';
            if(getComputedStyle)
                tmp.style.cssText = getComputedStyle(input, null).cssText;
            if(input.currentStyle)
                tmp.style.cssText = input.currentStyle.cssText;
            tmp.style.width = '';
            tmp.style.position = 'absolute';
            tmp.innerHTML = input.value.replace(/&/g, "&amp;")
                                       .replace(/</g, "&lt;")
                                       .replace(/>/g, "&gt;")
                                       .replace(/"/g, "&quot;")
                                       .replace(/'/g, "&#039;")
                                       .replace(/ /g, '&nbsp;');
            input.parentNode.appendChild(tmp);
            var width = tmp.clientWidth+pad_right+1;
            tmp.parentNode.removeChild(tmp);
            if(min <= width && width <= max)
                input.style.width = width+'px';
        }, 1);
    }
})();

JSFiddle

Paul
quelle
Danke für diesen einen. Ich habe mich entschieden, dies mit einem inhaltsbearbeitbaren Attribut zu tun, für das jedoch kein js erforderlich ist.
Stann
33
"Ich habe das gerade für dich geschrieben". +1 für die Anstrengung :)
Kevin Martin Jose
Wie erlaube ich dies, mehr als 1 (4) Eingabe mitid='adjinput'
teachtyler
sehr kreativ Ich liebe es
Deryck
2
Dies setzt voraus, dass Inhaltsänderungen nur über eine Tastatur erfolgen.
27.
6

Wie wäre es mit einer programmgesteuerten Änderung des Größenattributs für die Eingabe?

Semantisch (imo) ist diese Lösung besser als die akzeptierte Lösung, da sie weiterhin Eingabefelder für Benutzereingaben verwendet, aber ein wenig jQuery einführt. Soundcloud macht etwas Ähnliches für ihre Kennzeichnung.

<input size="1" />

$('input').on('keydown', function(evt) {
    var $this = $(this),
        size = parseInt($this.attr('size'), 10),
        isValidKey = (evt.which >= 65 && evt.which <= 90) || // a-zA-Z
                     (evt.which >= 48 && evt.which <= 57) || // 0-9
                     evt.which === 32;

    if ( evt.which === 8 && size > 0 ) {
        // backspace
        $this.attr('size', size - 1);
    } else if ( isValidKey ) {
        // all other keystrokes
        $this.attr('size', size + 1);
    }
});

http://jsfiddle.net/Vu9ZT/

Muffen
quelle
2
Dies funktioniert nicht, wenn Sie den Text markieren und die Rücktaste drücken, da er nur als Größe 1 und nicht als Größe $ ('Eingabe') zählt. Val (). Länge
Abadaba
3
Ich denke, dass das Zählen value.lengthsowohl einfacher als auch zuverlässiger wäre.
Tomáš Zato - Wiedereinsetzung Monica
1
Entf-Taste lässt dies wachsen
Ricca
5

Wenn Sie den Bereich so einstellen, dass Folgendes angezeigt wird: Inline-Block, automatische horizontale und vertikale Größenänderung funktioniert sehr gut:

<span contenteditable="true" 
      style="display: inline-block;
             border: solid 1px black;
             min-width: 50px; 
             max-width: 200px">
</span>

lastmjs
quelle
3

Ein paar Dinge fallen mir ein:

Verwenden Sie einen onkeydownHandler in Ihrem Textfeld, messen Sie den Text * und erhöhen Sie die Größe des Textfelds entsprechend.

Fügen Sie :focusIhrem Textfeld eine CSS-Klasse mit einer größeren Breite hinzu. Dann wird Ihre Box größer, wenn Sie fokussiert sind. Das ist nicht genau das, wonach Sie fragen, aber ähnlich.

* Es ist nicht einfach, Text in Javascript zu messen. Schauen Sie sich diese Frage für einige Ideen an.

Seth
quelle
beste Antwort bisher. :focus { width: 100% }
Oldboy
3

Von: Gibt es ein jQuery-Autogrow-Plugin für Textfelder?


Eine Demo finden Sie hier: http://jsbin.com/ahaxe

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);
cmpolis
quelle
2

Hier können Sie so etwas ausprobieren

BEARBEITEN: ÜBERARBEITETES BEISPIEL (eine neue Lösung hinzugefügt) http://jsfiddle.net/jszjz/10/

Code-Erklärung

var jqThis = $('#adjinput'), //object of the input field in jQuery
    fontSize = parseInt( jqThis.css('font-size') ) / 2, //its font-size
    //its min Width (the box won't become smaller than this
    minWidth= parseInt( jqThis.css('min-width') ), 
    //its maxWidth (the box won't become bigger than this)
    maxWidth= parseInt( jqThis.css('max-width') );

jqThis.bind('keydown', function(e){ //on key down
   var newVal = (this.value.length * fontSize); //compute the new width

   if( newVal  > minWidth && newVal <= maxWidth ) //check to see if it is within Min and Max
       this.style.width = newVal + 'px'; //update the value.
});

und das CSS ist auch ziemlich einfach

#adjinput{
    max-width:200px !important;
    width:40px;
    min-width:40px;
    font-size:11px;
}

BEARBEITEN: Eine andere Lösung besteht darin, den Benutzer eingeben zu lassen, was er will, und bei Unschärfe (Fokus heraus) die Zeichenfolge (in derselben Schriftgröße) in ein Div zu legen - die Breite des Div zu zählen - und dann mit einem netten Animieren mit einem Cool zu animieren Lockerungseffekt Aktualisieren Sie die Breite der Eingabefelder. Der einzige Nachteil ist, dass das Eingabefeld "klein" bleibt, während der Benutzer tippt. Oder Sie können eine Zeitüberschreitung hinzufügen :) Sie können eine solche Lösung auch auf der obigen Geige überprüfen!

Pantelis
quelle
font-sizeist keine perfekte Lösung. Nicht schlecht und sicherlich keine Abwertung wert, aber versuchen iSie mehrmals, den Buchstaben zu tippen, und Sie werden sehr verzerrte Ergebnisse in der Größe sehen. Siehe meine Antwort für eine Lösung für dieses Problem.
Paul
siehe das zweite Beispiel in meiner Geige, das keine Schriftgröße verwendet und sich für Glätte entscheidet. Der erste wurde nur für Geschwindigkeit und Geschwindigkeit hinzugefügt - unter Beibehaltung dessen, was der Fragesteller wollte. Es scheint mir jedes Mal "schwer" zu sein, einen Div-Append-Text zu erstellen, seine Breite usw. usw. zu berechnen, für etwas so Einfaches.
Pantelis
Ich bin mir nicht sicher warum, aber Ihr zweites Beispiel ändert für mich überhaupt nicht die Größe. Denken Sie auch daran, dass meine Lösung (die ein temporäres Div und dergleichen erstellt) in einem modernen Browser auf einem durchschnittlich aktuellen Computer ungefähr 800 Mal pro Sekunde ausgeführt werden kann und auf 99,5 wahrscheinlich nicht viel langsamer als 100 Mal pro Sekunde wird % der Computer, die heute noch verwendet werden)
Paul
2

Ich weiß, dass dies ein ernsthaft alter Beitrag ist - aber meine Antwort könnte trotzdem für andere nützlich sein, also geht es weiter. Ich habe festgestellt, dass das Div automatisch skaliert, wenn meine CSS-Stildefinition für das inhaltsbearbeitbare Div eine Mindesthöhe von 200 anstelle einer Höhe von 200 hat.

b0rgBart3
quelle
1

Wenn Sie nur in wachsenden interessiert sind, können Sie das Update widthauf scrollWidth, sobald der Inhalt des inputElements ändert.

document.querySelectorAll('input[type="text"]').forEach(function(node) {
  node.onchange = node.oninput = function() {
    node.style.width = node.scrollWidth+'px';
  };
});

Dies wird das Element jedoch nicht verkleinern.

ceving
quelle
1

Welchen Ansatz Sie verwenden, hängt natürlich davon ab, was Ihr Endziel ist. Wenn Sie die Ergebnisse mit einem Formular senden möchten, bedeutet die Verwendung nativer Formularelemente, dass Sie zum Senden kein Skript verwenden müssen. Wenn die Skripterstellung deaktiviert ist, funktioniert der Fallback auch ohne die ausgefallenen Grow-Shrink-Effekte. Wenn Sie den Klartext aus einem inhaltsbearbeitbaren Element herausholen möchten , können Sie jederzeit auch Skripte wie node.textContent verwenden , um das HTML zu entfernen , das die Browser in die Benutzereingabe einfügen.

Diese Version verwendet native Formularelemente mit geringfügigen Verbesserungen in einigen der vorherigen Beiträge.

Dadurch kann auch der Inhalt verkleinert werden.

Verwenden Sie dies in Kombination mit CSS für eine bessere Kontrolle.

<html>

<textarea></textarea>
<br>
<input type="text">


<style>

textarea {
  width: 300px;
  min-height: 100px;
}

input {
  min-width: 300px;
}


<script>

document.querySelectorAll('input[type="text"]').forEach(function(node) {
  var minWidth = parseInt(getComputedStyle(node).minWidth) || node.clientWidth;
  node.style.overflowX = 'auto'; // 'hidden'
  node.onchange = node.oninput = function() {
    node.style.width = minWidth + 'px';
    node.style.width = node.scrollWidth + 'px';
  };
});

Sie können etwas Ähnliches mit <textarea> -Elementen verwenden

document.querySelectorAll('textarea').forEach(function(node) {
  var minHeight = parseInt(getComputedStyle(node).minHeight) || node.clientHeight;
  node.style.overflowY = 'auto'; // 'hidden'
  node.onchange = node.oninput = function() {
    node.style.height = minHeight + 'px';
    node.style.height = node.scrollHeight + 'px';
  };
});

Dies flackert in Chrome nicht. Die Ergebnisse können in anderen Browsern variieren. Testen Sie daher.

Kevin Douglas
quelle
0

Hier ist eine Methode, die für mich funktioniert hat. Wenn Sie in das Feld eingeben, wird dieser Text in den ausgeblendeten Bereich eingefügt, erhält dann seine neue Breite und wendet ihn auf das Eingabefeld an. Es wächst und schrumpft mit Ihrer Eingabe, wobei ein Schutz gegen die Eingabe praktisch verschwindet, wenn Sie alle Eingaben löschen. In Chrome getestet. (BEARBEITEN: funktioniert zum Zeitpunkt dieser Bearbeitung in Safari, Firefox und Edge)

function travel_keyup(e)
{
    if (e.target.value.length == 0) return;
    var oSpan=document.querySelector('#menu-enter-travel span');
    oSpan.textContent=e.target.value;
    match_span(e.target, oSpan);
}
function travel_keydown(e)
{
    if (e.key.length == 1)
    {
        if (e.target.maxLength == e.target.value.length) return;
        var oSpan=document.querySelector('#menu-enter-travel span');
        oSpan.textContent=e.target.value + '' + e.key;
        match_span(e.target, oSpan);
    }
}
function match_span(oInput, oSpan)
{
    oInput.style.width=oSpan.getBoundingClientRect().width + 'px';
}

window.addEventListener('load', function()
{
    var oInput=document.querySelector('#menu-enter-travel input');
    oInput.addEventListener('keyup', travel_keyup);
    oInput.addEventListener('keydown', travel_keydown);

    match_span(oInput, document.querySelector('#menu-enter-travel span'));
});
#menu-enter-travel input
{
	width: 8px;
}
#menu-enter-travel span
{
	visibility: hidden;
    position: absolute;
    top: 0px;
    left: 0px;
}
<div id="menu-enter-travel">
<input type="text" pattern="^[0-9]{1,4}$" maxlength="4">KM
<span>9</span>
</div>

Aaron Mason
quelle
0

Wenn Sie die ch-Messung (monospaced) verwenden dürfen, hat sie das, was ich versucht habe, vollständig gelöst.

onChange(e => {
    e.target.style.width = `${e.target.length}ch`;
})

Dies war genau das, was ich brauchte, aber ich bin mir nicht sicher, ob es für Schriftfamilien mit dynamischer Breite funktioniert.

jscul
quelle