it-swarm.com.de

CSS-Textbereich, der beim Eingeben von Text erweitert wird

Ich habe einen Textbereich, in den Benutzer Text eingeben können. Standardmäßig hat es eine Höhe von 17px. Wenn Benutzer jedoch eine große Menge Text einfügen, möchte ich, dass der Textbereich entsprechend erweitert wird. Gibt es eine Möglichkeit, dies mit CSS zu tun? Danke im Voraus!!

37
Spencer

Dies ist nicht nur mit CSS möglich. Probieren Sie das automatische Jquery-Plugin aus. https://github.com/jaz303/jquery-grab-bag/blob/master/javascripts/jquery.autogrow-textarea.js

Sie können auch die Demo zu Autogrow hier sehen http://onehackoranother.com/projects/jquery/jquery-grab-bag/autogrow-textarea.html

Es ist leicht und einfach zu bedienen. So wird's gemacht. Definieren Sie Ihre Textarea-ID. Fügen Sie die jquery-js-Datei vor </body> ein. Geben Sie dann zwischen Skript-Tags den Jquery-Befehl $("#txtInput").autoGrow(); aus.

<body>
    <textarea id="txtInput"></textarea>
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.4.4/jquery.min.js" type="text/javascript"></script> 

<script>
    $("#txtInput").autogrow();
</script>
</body>
23
Hussein

Dieses jQuery-Plugin ist ein wirklich tolles Plugin: http://www.jacklmoore.com/autosize

Ich habe ein paar davon getestet und das ist bei weitem das Schönste. Gibt auch ein Beispiel für die Verwendung eines CSS-Übergangseffekts, der ziemlich glatt ist.

20
sirkitree

** Beachten Sie, dass dies Woodys Antwort sehr ähnlich ist, aber ich wollte etwas näher darauf eingehen und ein laufendes Codebeispiel bereitstellen, da Stack jetzt erlaubt, sie einzubetten.

Nachdem ich das alles durchgelesen und ein paar Plugins ausprobiert hatte, stellte ich fest, dass das alles nicht so funktionierte, wie ich gehofft hatte. Ich habe folgendes getan - es gibt einen leichten Jitter am oberen Rand des Feldes, wenn Sie scrollen, bevor es sich erweitert, aber es funktioniert für mich. Ich habe jquery verwendet, kann aber genauso einfach mit Javascript ausgeführt werden, indem ich die Auffüllwerte anstelle der Innenhöhe nehme:

  • Legen Sie im Textfeld in css eine Mindesthöhe fest
  • Stellen Sie den Überlauf für vertikales Scrollen auf ausgeblendet (ich wollte nur vertikal erweitern)
  • Legen Sie für jedes Keyup-Ereignis die Höhe auf die Höhe der Bildlaufhöhe ohne Auffüllung fest, wenn die Bildlaufhöhe höher als Höhe + Auffüllung (innere Höhe) war.
  • Wenn die Bildlaufhöhe nicht höher war, stelle ich die Höhe wieder auf 1 ein und stelle dann die Höhe auf die Bildlaufhöhe mit weniger Füllungen ein (um die Höhe zu verringern). Wenn Sie zunächst nicht auf eine kleinere Höhe zurücksetzen, wird die Bildlaufhöhe nicht verkleinert.

$(function() {
  $('#myTextArea').on('keyup paste', function() {
    var $el = $(this),
        offset = $el.innerHeight() - $el.height();

    if ($el.innerHeight < this.scrollHeight) {
      //Grow the field if scroll height is smaller
      $el.height(this.scrollHeight - offset);
    } else {
      //Shrink the field and then re-set it to the scroll height in case it needs to shrink
      $el.height(1);
      $el.height(this.scrollHeight - offset);
    }
  });
});
#myTextArea {
  width: 250px;
  min-height: 35px;
  overflow-y: hidden;
}
<script src="https://code.jquery.com/jquery-2.2.3.min.js"></script>
<textarea id="myTextArea" placeholder="Hit enter a few times, it should expand"></textarea>

15

Sie benötigen dafür kein Plugin. Dies funktioniert in Textbereichen mit beliebiger Größe, Höhe oder Zeilengröße und funktioniert nur, wenn der Inhalt den Textbereich überschreitet. Legen Sie zunächst den Überlauf in den Zieltextbereichen so fest, dass er ausgeblendet und in der Größe geändert wird, und fügen Sie dann den Textbereichen, die Sie automatisch vergrößern möchten, die folgende Funktionalität hinzu. Dadurch wird nicht nur die Größe des Textbereichs durch den Benutzer vergrößert, sondern auch beim Verkleinern automatisch verkleinert.

$('textarea').on('paste input', function () {
    if ($(this).outerHeight() > this.scrollHeight){
        $(this).height(1)
    }
    while ($(this).outerHeight() < this.scrollHeight + parseFloat($(this).css("borderTopWidth")) + parseFloat($(this).css("borderBottomWidth"))){
        $(this).height($(this).height() + 1)
    }
});

Es misst, ob die Bildlaufhöhe des Textbereichs größer als die äußere Höhe ist. Dies ist nur der Fall, wenn mehr Text vorhanden ist, als der Textbereich aufnehmen kann. Außerdem wird die Randgröße für eine höhere Genauigkeit berücksichtigt. Durch Einfügen und Eingabe wird der Wert nur erhöht, wenn der Benutzer den Wert des Textbereichs physisch ändert, im Gegensatz zum Drücken einer beliebigen Taste. Es ist kleinlich, aber ein Textfeld sollte nicht größer werden, wenn jemand eine Pfeiltaste oder etwas drückt.

Es ist möglicherweise ratsam, eine No-JS-Option hinzuzufügen, die den Überlauf und die Größenänderung für diejenigen aktiviert, die kein Javascript haben. Andernfalls werden sie mit einer winzigen Box blockiert.

12
Woody Payne

Ich weiß, dass dies etwas spät ist, aber ich muss sagen, dass es eine Möglichkeit gibt, <div> mit dem contenteditable-Attribut zu verwenden, um das gewünschte Verhalten zu simulieren.

.textareaElement {
  width: 300px;
  min-height: 17px;
  border: 1px solid #ccc;
  max-height: 150px;
  overflow-x: hidden;
  overflow-y: auto;
}
<div class="textareaElement" contenteditable></div>

Legen Sie einfach Ihre minimale und maximale Höhe mit den richtigen Überlaufwerten fest, und Sie verfügen über ein voll funktionsfähiges, reines CSS-Erweiterungsfeld, das auch gut unterstützt wird.

 enter image description here

10
Moo

Verwenden Sie dazu JavaScript.

Dieses Skript überprüft die Länge des Textbereichs nach jedem Tastendruck (copypasta von here ):

  <textarea name="x" onKeyUp="SetNewSize(this);" cols="5" rows="4"></textarea>
    <script language="javascript">
    function SetNewSize(textarea){
      if (textarea.value.length > 5){
        textarea.cols = 50;
        textarea.rows = 50;
      }  else{
         textarea.cols = 10;
         textarea.rows = 15;
      }
    }
  </script>
4
Nikita Barsukov

Dies scheint viel effizienter zu sein und kann mit der maximalen Höhe umgehen

$(ctrl).on('paste input', function () {
    var dyLineHeight, dyMax, dyHeight;        
    if ($(this).outerHeight() > this.scrollHeight)
        $(this).height($(this).outerHeight() - parseFloat($(this).css("borderBottomWidth")) - parseFloat($(this).css("borderTopWidth")));
    dyLineHeight = Math.max(3, parseInt($(this).css("line-height")));
    dyMax = parseInt($(this).css("max-height"));
    while ($(this).outerHeight() < this.scrollHeight + parseFloat($(this).css("borderTopWidth")) + parseFloat($(this).css("borderBottomWidth")))
        {
        dyHeight = $(this).height();
        if (dyHeight >= dyMax)
            break;
        $(this).height(dyHeight + dyLineHeight)
        }
});
1
Glenn Kreisel

Ein bisschen spät, aber das hat für mich wie ein Zauber gewirkt, es ist in jquery:

Dieses Textfeld hat eine maximale Höhe von 200px und eine Anfangshöhe von 22px. Das Auffüllen hilft sehr, den Text an einem guten Ort zu halten, aber wir müssen mit Gewichten spielen, die von der Schriftgröße abhängen.

Bei einer anderen Frage gibt es eine ähnliche Antwort, diese ist jedoch etwas vollständiger.

$('textarea').each(function () {
  // Do something if you want
}).on('input', function () {
  this.style.height = 'auto';
  // Customize if you want
  this.style.height = (this.scrollHeight - 30) + 'px'; //The weight is 30
});
textarea{
    padding: 7px;
    width: 50%;
    height: 22px;
    max-height: 200px;
    resize: none;
    overflow-y: scroll;
    font-size: 16px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div>Textarea:</div>
<textarea></textarea>
1
N0XT

Textbereich während der Eingabe erweitern

Geben Sie etwas in den Textbereich ein, um den Effekt anzuzeigen

<script>    
function increseRows(selector)
{
    $(selector).attr("rows", $(selector).val().split("\n").length+1||2);
}
</script>

expanding textarea as you type

1

Ich suchte nach reiner js-Lösung (keine Jquery in Projekten) und am Ende eine eigene Lösung schreiben. Es ist sehr schnell, keine Kompatibilitätsprobleme und erfordert keine zusätzlichen Bibliotheken. 

Ein Detail, das Sie beachten sollten, ist, dass Sie die Größe des Felds anpassen müssen, bevor ein neues Zeichen angezeigt wird.

function updateSize(e) {
  let text = e.target.value + String.fromCharCode(event.keyCode);
  e.target.rows = text.split(/\r\n|\r|\n/).length;
}

function keyDownUpdateSize(e) {
  if (event.keyCode != 8 && event.keyCode != 46)
    updateSize(e);
}

function keyUpUpdateSize(e) {
  if (event.keyCode == 8 || event.keyCode == 46)
    updateSize(e);
}

    
  
document.querySelector(selector_to_your_textarea).addEventListener("keydown", keyDownUpdateSize);
document.querySelector(selector_to_your_textarea).addEventListener("keyup", keyUpUpdateSize);

1
Marek Kirejczyk

Alte Frage, aber Sie könnten so etwas tun:

html:

<textarea class="text-area" rows="1"></textarea>

jquery:

var baseH; // base scroll height

$('body')
    .one('focus.textarea', '.text-area', function(e) {
        baseH = this.scrollHeight;
    })
    .on('input.textarea', '.text-area', function(e) {
        if(baseH < this.scrollHeight) {
            $(this).height(0).height(this.scrollHeight);
        }
        else {
            $(this).height(0).height(baseH);
        }
    });

Auf diese Weise gilt die automatische Größenänderung für alle Textbereiche mit der Klasse "Textbereich". Schrumpft auch, wenn Text entfernt wird.

jsfiddle:

https://jsfiddle.net/rotaercz/46rhcqyn/

1
rotaercz

Ich verwende Folgendes (natürlich mit jQuery):

$(function () {
    'use strict';
    $("textarea").on('change keyup paste input', function () {
        $(this).attr("rows", Math.max($(this).val().split("\n").length || 1, $(this).attr("rows") || 1));
        $(this).css("width", $(this).css("width"));
    }).trigger('change');
});

Beachten Sie, dass es auf verschiedene Ereignisse reagiert, nur die Anzahl der Zeilen erhöht (d. H. Nicht verringert) und eine anfängliche Änderung auslöst (z. B. zum Ändern der Größe, wenn Sie zu einem Formular mit vielen Zeilen zurückkehren).

1
DigitalDan
var textarea = document.querySelector('textarea');
textarea.addEventListener('keydown', autosize);             
function autosize(){
  var el = this;
  setTimeout(function(){
    el.style.cssText = 'height:auto; padding:0';    
    el.style.cssText = 'height:' + el.scrollHeight + 'px';
  },0);
}
textarea{   
  overflow:hidden; 
  padding:10px;
  width:250px;
  font-size:14px;
  margin:50px auto;
  display:block;
  border-radius:10px;
  border:6px solid #556677;
}
<textarea rows="6" >
CSS Textarea that expands as you type text
rows Specifies the visible number of lines in a text area and cols      Specifies the visible width of a text area
</textarea>
0
rajmobiapp
function autoExpand(field) {

    // Reset field height
    field.style.height = 'inherit';

    // Get the computed styles for the element
    var computed = window.getComputedStyle(field);

    // Calculate the height
    var height = parseInt(computed.getPropertyValue('border-top-width'), 10)
                 + parseInt(computed.getPropertyValue('padding-top'), 10)
                 + field.scrollHeight
                 + parseInt(computed.getPropertyValue('padding-bottom'), 10)
                 + parseInt(computed.getPropertyValue('border-bottom-width'), 10);

    field.style.height = height + 'px';

};

Funktioniert bei mir

https://gomakethings.com/automatically-expand-a-textarea-as-the-user-types-using-Vanilla-javascript/

0
Mauro Salgado

Verwenden Sie Javascript. textarea verhält sich wie ein textarea, und Sie möchten dies ändern (Sie möchten, dass es sich wie ein div verhält), so dass Sie das Verhalten, das Sie möchten, hacken können.

Hier ist eine Lösung, die ich vor ein paar Monaten gefunden habe, die ich aber nicht wieder finden konnte. Es kann mein eigener Geschmack hinzugefügt werden in:

Markup:

<div>
  <textarea class='my-textarea' />
  <div className='my-textarea autogrow' style="display: 'none';" />
</div>

Styles:

.my-textarea {
  border: 1px solid #bbb;
  font-family: Helvetica;
  font-size: 15px;
  overflow: hidden;
  padding: 5px;
  resize: none;
}

// Needs same styles as the textarea except overflow.
.autogrow {
  overflow: auto !important;
}

Holen Sie sich diesen Ereignis-Listener auf das change-Ereignis des Textbereichs:

function growTextarea(e) {
  const { value } = e.target
  const textarea = e.target
  const { grower } = this

  grower.style.display = 'block'
  grower.innerHTML = value.length ? value : 'x'
  textarea.style.height = grower.offsetHeight + 'px'
  grower.style.display = 'none'
}

Wie funktioniert es? Grundsätzlich ist die Erweiterung eines Div das, was Sie möchten, damit sich die Textarea-Erweiterung verhält. Sie erstellen also ein div mit den gleichen Stilen wie das Textfeld und setzen den Wert des Textfelds in das div. Dann erhältst du die Höhe des div und setzt die Höhe des Textbereichs darauf.

Wenn Sie "Keine" und "Block" verwenden, wird das Div angezeigt und ausgeblendet, sodass Sie die Höhe messen können. Sie werden es nie im Browser sehen.

Hoffe das funktioniert für dich!

P.S. Ich benutze React, also musste ich meine Lösung ändern, um Framework-Agnostiker zu sein. Es kann also Fehler oder Syntaxfehler geben. Z.B. Möglicherweise müssen Sie das Dokument abfragen, um das wachsende div zu finden.

0
A.Williams

Wenn Sie Angular2/4 verwenden, gibt es eine großartige Direktive hier , die funktioniert. 

In der Problemliste finden Sie, wenn Sie Daten dynamisch für eine Problemumgehung in den Textbereich laden. Abgesehen von diesem Problem funktioniert es gut mit ReactiveForms- und Vorlagenformularen.

Dies ist der Direktive-Code:

import { Input, AfterViewInit, ElementRef, HostListener, Directive} from '@angular/core';

@Directive({
    selector: 'textarea[autosize]'
})

export class Autosize implements AfterViewInit {

    private el: HTMLElement;
    private _minHeight: string;
    private _maxHeight: string;
    private _lastHeight: number;
    private _clientWidth: number;

    @Input('minHeight')
    get minHeight() { 
      return this._minHeight;
    }
    set minHeight(val: string) {
      this._minHeight = val;
      this.updateMinHeight();
    }

    @Input('maxHeight')
    get maxHeight() {
      return this._maxHeight; 
    }
    set maxHeight(val: string) {
      this._maxHeight = val;
      this.updateMaxHeight();
    }

 @HostListener('window:resize', ['$event.target'])
    onResize(textArea: HTMLTextAreaElement) {
      //Only apply adjustment if element width had changed.
      if (this.el.clientWidth === this._clientWidth) return;
      this._clientWidth = this.element.nativeElement.clientWidth;
      this.adjust();
    }

 @HostListener('input',['$event.target'])
  onInput(textArea: HTMLTextAreaElement): void {
    this.adjust();  
  }

  constructor(public element: ElementRef){
    this.el = element.nativeElement;
    this._clientWidth = this.el.clientWidth;
  }

  ngAfterViewInit(): void{
    // set element resize allowed manually by user
    const style = window.getComputedStyle(this.el, null);
    if (style.resize === 'both') {
            this.el.style.resize = 'horizontal';
        }
    else if (style.resize === 'vertical') {
            this.el.style.resize = 'none';
    }
    // run first adjust
    this.adjust();
  }

  adjust(): void{
    // perform height adjustments after input changes, if height is different
    if (this.el.style.height == this.element.nativeElement.scrollHeight + "px") return;
    this.el.style.overflowX = 'hidden';
    this.el.style.height = 'auto';
    this.el.style.height = this.el.scrollHeight + "px";
  }

  updateMinHeight(): void{
    // Set textarea min height if input defined
    this.el.style.minHeight = this._minHeight + 'px';
  }

  updateMaxHeight(): void{
    // Set textarea max height if input defined
    this.el.style.maxHeight = this._maxHeight + 'px';
  }

}
0
rmcsharry