Espandi automaticamente una textarea usando jQuery

Come posso espandere automaticamente un’area di testo usando jQuery?

Ho una casella di testo per spiegare l’ordine del giorno della riunione, quindi voglio espandere quella casella di testo quando il testo della mia agenda continua a far crescere quell’area della casella di testo.

Ho provato un sacco e questo è fantastico. Link è morto. La versione più recente è disponibile qui . Vedi sotto per la vecchia versione.
Puoi provare premendo e tenendo premuto il tasto invio nella textarea. Confronta l’effetto con l’altro plug-in textarea in espansione automatica ….

modifica basata sul commento

$(function() { $('#txtMeetingAgenda').autogrow(); }); 

nota: dovresti includere i file js necessari …

Per evitare che la barra di scorrimento nell’area di testo si illumini e si spenga durante l’espansione / contrazione, puoi anche impostare l’ overflow su hidden :

 $('#textMeetingAgenda').css('overflow', 'hidden').autogrow() 


Aggiornare:

Il link sopra è rotto. Ma puoi ancora ottenere i file javascript qui .

Se non vuoi un plugin c’è una soluzione molto semplice

 $("textarea").keyup(function(e) { while($(this).outerHeight() < this.scrollHeight + parseFloat($(this).css("borderTopWidth")) + parseFloat($(this).css("borderBottomWidth"))) { $(this).height($(this).height()+1); }; }); 

Guardalo mentre lavora in un jsFiddle che ho usato per rispondere ad un'altra domanda nella textarea qui .

Per rispondere alla domanda di farlo al contrario o ridurlo man mano che il testo viene rimosso: jsFiddle

E se vuoi un plugin

@ Jason ne ha progettato uno qui

Cresce / riduce la textarea. Questa demo utilizza jQuery per l’associazione degli eventi, ma non è un obbligo in alcun modo.
( nessun supporto IE – IE non risponde alle modifiche degli attributi delle righe )

PAGINA DEMO


HTML

  

CSS

 textarea{ display:block; box-sizing: padding-box; overflow:hidden; padding:10px; width:250px; font-size:14px; margin:50px auto; border-radius:8px; border:6px solid #556677; } 

javascript (aggiornato)

 $(document) .one('focus.textarea', '.autoExpand', function(){ var savedValue = this.value; this.value = ''; this.baseScrollHeight = this.scrollHeight; this.value = savedValue; }) .on('input.textarea', '.autoExpand', function(){ var minRows = this.getAttribute('data-min-rows')|0, rows; this.rows = minRows; rows = Math.ceil((this.scrollHeight - this.baseScrollHeight) / 16); this.rows = minRows + rows; }); 
  • Textareas in crescita automatica
  • jQuery Autosize

Puoi provare questo

 $('#content').on('change keyup keydown paste cut', 'textarea', function () { $(this).height(0).height(this.scrollHeight); }).find('textarea').change(); 
  

Grazie a SpYk3HH, ho iniziato con la sua soluzione e l’ho trasformata in questa soluzione, che aggiunge la funzionalità di restringimento ed è ancora più semplice e veloce, presumo.

 $("textarea").keyup(function(e) { $(this).height(30); $(this).height(this.scrollHeight + parseFloat($(this).css("borderTopWidth")) + parseFloat($(this).css("borderBottomWidth"))); }); 

Testato negli attuali browser Chrome, Firefox e Android 2.3.3.

Potresti vedere dei flash delle barre di scorrimento in alcuni browser. Aggiungi questo CSS per risolverlo.

 textarea{ overflow:hidden; } 

Per definire una textarea auto espandibile, devi fare due cose:

  1. Espandilo quando fai clic sul tasto Invio al suo interno oppure digita il contenuto più di una riga.
  2. E rimpicciolisci a sfocatura per ottenere le dimensioni reali se l’utente ha inserito spazi bianchi. ( Bonus )

Ecco una funzione fatta a mano per svolgere il compito.

Funziona bene con quasi tutti i browser ( . Ecco il metodo:

  //Here is an event to get TextArea expand when you press Enter Key in it. // intiate a keypress event $('textarea').keypress(function (e) { if(e.which == 13) { var control = e.target; var controlHeight = $(control).height(); //add some height to existing height of control, I chose 17 as my line-height was 17 for the control $(control).height(controlHeight+17); } }); $('textarea').blur(function (e) { var textLines = $(this).val().trim().split(/\r*\n/).length; $(this).val($(this).val().trim()).height(textLines*17); }); 

QUI è un post su questo.

Ho usato il plugin jQuery Textarea Expander prima con buoni risultati.

Tutti dovrebbero provare questo plugin jQuery: xautoresize-jquery . È davvero buono e dovrebbe risolvere il tuo problema.

Ho appena creato questa funzione per espandere i textareas sul pageload. Basta cambiare each in keyup e avverrà quando si digita la textarea.

 // On page-load, auto-expand textareas to be tall enough to contain initial content $('textarea').each(function(){ var pad = parseInt($(this).css('padding-top')); if ($.browser.mozilla) $(this).height(1); var contentHeight = this.scrollHeight; if (!$.browser.mozilla) contentHeight -= pad * 2; if (contentHeight > $(this).height()) $(this).height(contentHeight); }); 

Testato su Chrome, IE9 e Firefox. Sfortunatamente Firefox ha questo bug che restituisce il valore errato per scrollHeight , quindi il codice sopra riportato contiene una soluzione alternativa (hacky) per questo.

Ho corretto alcuni bug nella risposta fornita da Reigel (la risposta accettata):

  1. L’ordine in cui le quadro html vengono sostituite ora non causa codice inaspettato nell’elemento ombra. (L’originale sostituito “>” da “& ampgt;”, causando il calcolo errato dell’altezza in alcuni rari casi).
  2. Se il testo termina con una nuova riga, l’ombra ora ottiene un carattere aggiuntivo “#”, invece di avere un’altezza aggiunta fissa, come nel caso dell’originale.
  3. Il ridimensionamento dell’area di testo dopo l’inizializzazione aggiorna la larghezza dell’ombra.
  4. aggiunto word-wrap: break-word per shadow, quindi si rompe come una textarea (forzando le interruzioni per parole molto lunghe)

Ci sono alcuni problemi rimanenti riguardo agli spazi. Non vedo una soluzione per i doppi spazi, sono visualizzati come spazi singoli nell’ombra (rendering html). Questo non può essere rimosso usando & nbsp ;, perché gli spazi dovrebbero interrompersi. Inoltre, la textarea rompe una linea dopo uno spazio, se non c’è spazio per quello spazio interromperà la linea in un punto precedente. I suggerimenti sono ben accetti

Codice corretto

 (function ($) { $.fn.autogrow = function (options) { var $this, minHeight, lineHeight, shadow, update; this.filter('textarea').each(function () { $this = $(this); minHeight = $this.height(); lineHeight = $this.css('lineHeight'); $this.css('overflow','hidden'); shadow = $('
').css({ position: 'absolute', 'word-wrap': 'break-word', top: -10000, left: -10000, width: $this.width(), fontSize: $this.css('fontSize'), fontFamily: $this.css('fontFamily'), lineHeight: $this.css('lineHeight'), resize: 'none' }).appendTo(document.body); update = function () { shadow.css('width', $(this).width()); var val = this.value.replace(/&/g, '&') .replace(//g, '>') .replace(/\n/g, '
') .replace(/\s/g,' '); if (val.indexOf('
', val.length - 5) !== -1) { val += '#'; } shadow.html(val); $(this).css('height', Math.max(shadow.height(), minHeight)); }; $this.change(update).keyup(update).keydown(update); update.apply(this); }); return this; }; }(jQuery));

Codice di SpYk3HH con aggiunta per il restringimento delle dimensioni.

 function get_height(elt) { return elt.scrollHeight + parseFloat($(elt).css("borderTopWidth")) + parseFloat($(elt).css("borderBottomWidth")); } $("textarea").keyup(function(e) { var found = 0; while (!found) { $(this).height($(this).height() - 10); while($(this).outerHeight() < get_height(this)) { $(this).height($(this).height() + 1); found = 1; }; } }); 
 function autosize(textarea) { $(textarea).height(1); // temporarily shrink textarea so that scrollHeight returns content height when content does not fill textarea $(textarea).height($(textarea).prop("scrollHeight")); } $(document).ready(function () { $(document).on("input", "textarea", function() { autosize(this); }); $("textarea").each(function () { autosize(this); }); }); 

(Questo non funzionerà in Internet Explorer 9 o precedente poiché utilizza l’evento di input )

Questo ha funzionato per me meglio:

 $('.resiText').on('keyup input', function() { $(this).css('height', 'auto').css('height', this.scrollHeight + (this.offsetHeight - this.clientHeight)); }); 
 .resiText { box-sizing: border-box; resize: none; } 
   

Le persone sembrano avere soluzioni molto elaborate …

Ecco come lo faccio:

  $('textarea').keyup(function() { var $this = $(this), height = parseInt($this.css('line-height'), 10), padTop = parseInt($this.css('padding-top'), 10), padBot = parseInt($this.css('padding-bottom'), 10); $this.height(0); var scroll = $this.prop('scrollHeight'), lines = (scroll - padTop - padBot) / height; $this.height(height * lines); }); 

Questo funzionerà con le linee lunghe, così come le interruzioni di riga .. cresce e si restringe ..

Ho scritto questa funzione jQuery che sembra funzionare.

Devi però specificare min-height in css e, a meno che tu non voglia fare del codice, deve essere lungo due cifre. cioè 12px;

 $.fn.expand_ta = function() { var val = $(this).val(); val = val.replace(//g, ">"); val += "___"; var ta_class = $(this).attr("class"); var ta_width = $(this).width(); var min_height = $(this).css("min-height").substr(0, 2); min_height = parseInt(min_height); $("#pixel_height").remove(); $("body").append('

'); $("#pixel_height").html(val); var height = $("#pixel_height").height(); if (val.substr(-6) == "
"){ height = height + min_height; }; if (height >= min_height) $(this).css("height", height+"px"); else $(this).css("height", min_height+"px"); }

Per chiunque utilizzi il plug-in inviato da Reigel, tieni presente che ciò disabiliterà la funzionalità di annullamento in Internet Explorer (vai a dare la demo).

Se questo è un problema per te, ti suggerisco di utilizzare il plugin pubblicato da @richsage, in quanto non soffre di questo problema. Per ulteriori informazioni, vedere il secondo punto elenco su Ricerca dell’area di testo di ridimensionamento definitiva .

C’è anche il fantastico progetto bgrins/ExpandingTextareas (github) , basato su una pubblicazione di Neill Jenkins chiamata Expanding Text Areas Made Elegant

Volevo animazioni e auto-restringimento. La combinazione è apparentemente difficile, perché le persone hanno trovato soluzioni piuttosto intense per questo. L’ho reso anche multi-testuale. E non è così ridicolmente pesante come il plugin jQuery.

Mi sono basato sulla risposta di vsync (e sul miglioramento che ha apportato), http://codepen.io/anon/pen/vlIwj è il codice per il mio miglioramento.

HTML

  

CSS

 body{ background:#728EB2; } textarea{ display:block; box-sizing: padding-box; overflow:hidden; padding:10px; width:250px; font-size:14px; margin:50px auto; border-radius:8px; border:6px solid #556677; transition:all 1s; -webkit-transition:all 1s; } 

JS

 var rowheight = 0; $(document).on('input.textarea', '.autoExpand', function(){ var minRows = this.getAttribute('data-min-rows')|0, rows = this.value.split("\n").length; $this = $(this); var rowz = rows < minRows ? minRows : rows; var rowheight = $this.attr('data-rowheight'); if(!rowheight){ this.rows = rowz; $this.attr('data-rowheight', (this.clientHeight - parseInt($this.css('padding-top')) - parseInt($this.css('padding-bottom')))/ rowz); }else{ rowz++; this.style.cssText = 'height:' + rowz * rowheight + 'px'; } }); 

Ci sono molte risposte per questo, ma ho trovato qualcosa di molto semplice, associare un evento keyup alla textarea e controllare se il tasto invio è premuto, il codice chiave è 13

keyPressHandler(e){ if(e.keyCode == 13){ e.target.rows = e.target.rows + 1; } }

Questo aggiungerà un’altra riga alla tua textarea e potrai ridimensionare la larghezza usando i CSS.

Diciamo che stai provando a farlo usando Knockout … ecco come:

Nella pagina:

  

In vista modello:

 self.GrowTextArea = function (data, event) { $('#' + event.target.id).height(0).height(event.target.scrollHeight); } 

Questo dovrebbe funzionare anche se hai più aree di testo create da un Knockout foreach come faccio io.

Soluzione semplice:

HTML:

  

JS:

 $('textarea.expand').on('input', function() { $(this).scrollTop($(this).height()); }); $('textarea.expand').scroll(function() { var h = $(this).scrollTop(); if (h > 0) $(this).height($(this).height() + h); }); 

https://fiddle.jshell.net/7wsnwbzg/

@Georgiy Ivankin ha fatto un suggerimento in un commento, l’ho usato con successo 🙂 -, ma con lievi modifiche:

 $('#note').on('keyup',function(e){ var maxHeight = 200; var f = document.getElementById('note'); if (f.clientHeight < f.scrollHeight && f.scrollHeight < maxHeight ) { f.style.height = f.scrollHeight + 'px'; } }); 

Arresta l'espansione dopo aver raggiunto l'altezza massima di 200 px

La soluzione più semplice:

html:

  

css:

 .auto-expand { overflow:hidden; min-height: 80px; } 

js (jquery):

 $(document).ready(function () { $("textarea.auto-expand").focus(function () { var $minHeight = $(this).css('min-height'); $(this).on('input', function (e) { $(this).css('height', $minHeight); var $newHeight = $(this)[0].scrollHeight; $(this).css('height', $newHeight); }); }); }); 

Vecchia domanda ma potresti fare qualcosa del genere:

html:

  

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

In questo modo l'auto ridimensionamento si applicherà a qualsiasi textarea con la class "text-area". Si restringe anche quando il testo viene rimosso.

jsfiddle:

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

Soluzione con puro JS

 function autoSize() { if (element) { element.setAttribute('rows', 2) // minimum rows const rowsRequired = parseInt( (element.scrollHeight - TEXTAREA_CONFIG.PADDING) / TEXTAREA_CONFIG.LINE_HEIGHT ) if (rowsRequired !== parseInt(element.getAttribute('rows'))) { element.setAttribute('rows', rowsRequired) } } } 

https://jsfiddle.net/Samb102/cjqa2kf4/54/

Questa è la soluzione che ho finito per usare. Volevo una soluzione in linea, e questo finora sembra funzionare alla grande: