JQuery kullanarak bir metin alanını otomatik olarak genişletme


128

JQuery kullanarak bir metin alanını otomatik olarak nasıl genişletebilirim?

Toplantının gündemini açıklamak için bir metin kutum var, bu nedenle ajandamın metni bu metin kutusu alanını büyütmeye devam ettiğinde bu metin kutusunu genişletmek istiyorum.


i bu metin alanı otomatik olarak genişletilebilir.
andrew Sullivan


Lütfen sorunuzu değiştirmeyi ve "jQuery" kelimesini kaldırmayı düşünün
vsync

Yanıtlar:


113

Çok denedim ve bu harika. Bağlantı öldü. Daha yeni sürüm burada mevcuttur . Eski sürüm için aşağıya bakın.
Metin alanında enter tuşuna basılı tutarak deneyebilirsiniz. Efekti diğer otomatik genişleyen metin alanı eklentisiyle karşılaştırın ....

yoruma göre düzenle

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

not: gerekli js dosyalarını eklemelisiniz ...

Genişleme / daralma sırasında & kapalı yanıp sönen gelen textarea kaydırma çubuğu önlemek için ayarlayabilirsiniz overflowiçin hiddensıra:

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




Güncelleme:

Yukarıdaki bağlantı koptu. Ama yine de javascript dosyalarını buradan alabilirsiniz .


Benim metin kutusu kimliği ise txtMeetingAgenda sonra ben jquery Otomatik textarea özelliği nasıl uygulayabileceğiniz
Piyush

Burada Tıklama etkinliği tanımlamak olup olmadığını
Piyush

bu tamamen textarea ile ilgili peki ya textbox. bu eklenti textbox için de çalışıyor mu?
Piyush

1
Bu eklenti, deneyin autosize, iyi 's çalışmıyor yolu daha iyi
julesbou

Metin alanı büyüdüğünde yalnızca bir şekilde iyi çalışır. Ancak metni silmeye başladığınızda, otomatik olarak yüksekliği azaltmaz.
ekashking

166

Bir eklenti istemiyorsanız çok basit bir çözüm var

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

Bir jsFiddle içinde çalıştığını görün. Burada başka bir metin alanı sorusunu yanıtlardım .

Metin kaldırıldıkça bunu tersten yapmak veya küçültmek sorusuna cevap vermek için: jsFiddle

Ve bir eklenti istiyorsanız

@Jason burada bir tane tasarladı


1
+ ParseFloat ($ (this) .css ("borderTopWidth")) + parseFloat ($ (this) .css ("borderBottomWidth")) kaldırmak zorunda kaldım, aksi takdirde bootstrap ile biçimlendirilmiş bir textarea ile sonsuz döngüye
giriyor

3
if (this.clientHeight < this.scrollHeight) { this.style.height = this.scrollHeight + 'px'; }
jQuery'siz

3
@metakungfu Sadece olumsuz oy vermek yerine, cevabı iyileştirmeye yardımcı olabilirsiniz. Apple crap atm'yi test etmenin hiçbir yolu yok ve windows için safari uzun zaman önce kesildi. Bu yüzden neden işe yaramayacağını belirlemek için hiçbir şey yapamıyorum. Kod açısından, bu çözümde yanlış bir şey yok. Jsfiddle'da safariyi bozmanın değil, kodun kırıldığından emin misin? safari oldukça seçici ve keman büyük bir güncellemeden geçti. Mayeb, dev con açıp biraz daha detay verebilir misin?
SpYk3HH

1
ayrıca yanıp sönen kaydırmayı önlemek için textarea overflow-y'nin gizli olarak ayarlanması gerekiyor
iulial

2
Eklenen satırları kaldırmak istersem, metin kutusunun büyütülmüş boyutu aynı kalır, otomatik olarak yeniden boyutlandırması da mümkün müdür?
Steven

33

Metin alanını büyütür / küçültür. Bu demo, olay bağlama için jQuery kullanır, ancak hiçbir şekilde bir zorunluluk değildir.
( IE desteği yok - IE, satır özellik değişikliğine yanıt vermiyor )

DEMO SAYFASI


HTML

<textarea class='autoExpand' rows='3' data-min-rows='3' placeholder='Auto-Expanding Textarea'></textarea>

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 (güncellendi)

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

2
çünkü kod, yazdığınız mektubun metin alanına yazdırılması için biraz beklemeli ve bu nedenle metin alanının boyutlarını değiştirmelidir
vsync

1
Görüyorum ki, metin herhangi bir kaynaktan kopyalandığında (CTRL + V) çözüm bozulmuş. Bununla birlikte, metin manuel olarak yazılırsa - bu harika ve çok düzgün.
Satya Kalluri

1
@vsync: Birden çok metin alanı için nasıl değişiklik yapardınız? Yani textarea1 ve textarea2 var ve ikisinin de büyümesine izin vermek mi istiyorsunuz?
jmoreno

1
Bu en iyi cevap olmalı! İlgilenen varsa buna dayalı bir soru yayınladım: stackoverflow.com/questions/29930300/…
gsamaras

1
@AllyMurray - Şimdi gittim ve daha iyi sonuç veriyor gibi göründüğü için 16'ya güncelledim. ve evet, bu beklenen satır yüksekliği
vsync


20

Bunu deneyebilirsin

$('#content').on('change keyup keydown paste cut', 'textarea', function () {
        $(this).height(0).height(this.scrollHeight);
    }).find('textarea').change();
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<div id="content">
  <textarea>How about it</textarea><br />
  <textarea rows="5">111111
222222
333333
444444
555555
666666</textarea>
</div>


scrollHeight'ı $ (this) 'dan almak istiyorsanız, $ (this) .prop (' scrollHeight '); yerine;)
Samuel Vicent

3
her satır sonunda yanıp söner
joe

11

SpYk3HH sayesinde onun çözümüyle başladım ve onu küçültme işlevselliği ekleyen ve daha da basit ve daha hızlı olan bu çözüme çevirdim sanırım.

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

Mevcut Chrome, Firefox ve Android 2.3.3 tarayıcısında test edilmiştir.

Bazı tarayıcılarda kaydırma çubuklarının yanıp söndüğünü görebilirsiniz. Bunu çözmek için bu CSS'yi ekleyin.

textarea{ overflow:hidden; }

hiç iyi çalışmıyor: / yazdığım her karakter, yükseklik katıyor.
vsync

1
Benim için mükemmel çalışıyor! Basit kodda, söylediğinizi yapacak hiçbir şey kesinlikle yoktur.
drolex

1
evet şimdi görüyorum, kodunuzun başlangıçta yüksekliği 30'a ayarlayan satıra sahip olması gerekir. bu muhtemelen ihtiyaç duyulmayan bir durumdur çünkü geliştiriciyi, kodu anlamak ve metin alanını uyarlamak yerine kodu değiştirmeye zorlar,
vsync

1
Bu yanlış. Geliştiricinin kodu değiştirmesine gerek yoktur. Yüksekliğin 30'a ayarlanması gerekir ve her şey için işe yarar. Kullanıcı bunun olduğunu asla görmez. Metin alanını bu şekilde küçültebilir. Kod, metin alanını anlar ve ona uyarlanır. Bütün mesele bu.
drolex

Haklısın. demo sayfası: jsbin.com/ObEcoza/2/edit (yüksekliği 1pxdaha iyi görünecek şekilde ayarlamak )
vsync

10

Otomatik olarak genişletilebilir bir metin alanı tanımlamak için iki şey yapmanız gerekir:

  1. genişletmekİçerisindeki Enter tuşuna tıkladığınızda veya birden fazla satır içeriği yazın.
  2. Ve küçültmek kullanıcı beyaz boşluk girmiş eğer gerçek boyutunu almak için bulanıklık adresinden. ( Bonus )

Burada bir görevi yerine getirmek için el yapımı bir işlev .

Neredeyse tüm tarayıcılarla iyi çalışıyor (<IE7) . İşte yöntem:

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

BURADA bununla ilgili bir gönderi var.


6

Ben kullandım Metin Alanı Genişletici iyi sonuçlarla önce jQuery eklentisi.


1
Bir metin kutusu (sanırım girdi metin öğesi) çok satırlı değil. Bir metin alanı kullanın, ancak uygun şekilde biçimlendirin - satırlar, sütunlar vb. Ve ardından yukarıdaki gibi otomatik büyütme eklentisini kullanın.
richsage


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

(Bu, inputolayı kullandığından Internet Explorer 9 veya daha eski sürümlerde çalışmaz )



3

Bu işlevi, sayfa yükünde metin alanlarını genişletmek için oluşturdum. Sadece değiştirmek eachiçin keyupve textarea yazıldığında ne zaman ortaya çıkar.

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

Chrome, IE9 ve Firefox'ta test edilmiştir. Ne yazık ki Firefox'ta yanlış değeri döndüren bu hata var scrollHeight, bu nedenle yukarıdaki kod bunun için bir (hacky) geçici çözüm içeriyor.


3

Reigel tarafından sağlanan cevaptaki birkaç hatayı düzelttim (kabul edilen cevap):

  1. Şimdi html varlıklarının değiştirilme sırası, gölge öğesinde beklenmeyen koda neden olmaz. (Orijinal, ">" ile "& ampgt;" değiştirildi ve bazı nadir durumlarda yanlış yükseklik hesaplamasına neden oldu).
  2. Metin bir satırsonu ile bitiyorsa, orijinalde olduğu gibi, gölge artık sabit bir yüksekliğe sahip olmak yerine fazladan bir "#" karakteri alır.
  3. İlklendirmeden sonra metin alanının yeniden boyutlandırılması gölgenin genişliğini günceller.
  4. kelime kaydırma eklendi: gölge için ara kelime, böylece bir metin alanıyla aynı şeyi bozar (çok uzun kelimeler için araları zorlar)

Alanlarla ilgili kalan bazı sorunlar var. Çift boşluklar için bir çözüm görmüyorum, gölgede tek boşluklar olarak görüntüleniyorlar (html oluşturma). Boşlukların kırılması gerektiğinden, bu & nbsp; kullanılarak ekilemez. Ayrıca, metin alanı bir boşluktan sonra bir satırı keser, bu boşluk için yer yoksa, satırı daha önceki bir noktada keser. Önerilere açığız.

Düzeltilmiş kod:

(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 = $('<div></div>').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, '&amp;')
                                    .replace(/</g, '&lt;')
                                    .replace(/>/g, '&gt;')
                                    .replace(/\n/g, '<br/>')
                                    .replace(/\s/g,'&nbsp;');
                if (val.indexOf('<br/>', 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));

3

Küçültme boyutu için eklenmiş SpYk3HH kodu.

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

Cevabımı senden önce gördün mü?
drolex

1
Çözümünüz bana uymuyor, bir hata oluştu, hangisi olduğunu hatırlamıyorum.
DSblizzard 13

2

Bu benim için daha iyi çalıştı:

$('.resiText').on('keyup input', function() { 
$(this).css('height', 'auto').css('height', this.scrollHeight + (this.offsetHeight - this.clientHeight));
});
.resiText {
    box-sizing: border-box;
    resize: none;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<textarea class="resiText"></textarea>


2

İnsanların çok fazla çalışılmış çözümleri var gibi görünüyor ...

Ben böyle yaparım:

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

Bu, uzun satırlarda olduğu gibi satır sonlarında da işe yarar .. büyür ve küçülür ..


1

Çalışıyor gibi görünen bu jquery işlevini yazdım.

Yine de css'de minimum yükseklik belirtmeniz gerekir ve bazı kodlamalar yapmak istemiyorsanız, iki basamak uzunluğunda olması gerekir. yani 12px;

$.fn.expand_ta = function() {

var val = $(this).val();
val = val.replace(/</g, "&lt;");
val = val.replace(/>/g, "&gt;");
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('<pre class="'+ta_class+'" id="pixel_height" style="position: absolute; white-space: pre-wrap; visibility: hidden; word-wrap: break-word; width: '+ta_width+'px; height: auto;"></pre>');
$("#pixel_height").html(val);

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



1

Animasyonlar ve otomatik küçültme istedim. Görünüşe göre kombinasyon zor, çünkü insanlar bunun için oldukça yoğun çözümler buldu. Ben de çoklu metin alanına karşı korumalı yaptım. Ve jQuery eklentisi kadar gülünç derecede ağır değil.

Kendimi vsync'in cevabına (ve onun için yaptığı iyileştirmeye) dayandırdım , http://codepen.io/anon/pen/vlIwj , iyileştirmem için kodepen.

HTML

<textarea class='autoExpand' rows='3' data-min-rows='3' placeholder='Auto-Expanding Textarea'></textarea>

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

Not: Bazen kutu boyutlandırma: içerik kutusu ile daha iyi çalıştığını fark ettim. Yine de neden dolguyu doğru şekilde işlemesi gerektiğinden tam olarak emin değilim :(
Lodewijk

1

Bunun için birçok cevap var ama çok basit bir şey buldum, metin alanına bir keyup olayı ekledim ve giriş tuşunu kontrol et, anahtar kodu 13

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

Bu size metin alanına başka bir satır ekleyecek ve genişliği CSS kullanarak biçimlendirebilirsiniz.


1

Diyelim ki bunu Knockout kullanarak başarmaya çalışıyorsunuz ... işte nasıl:

Sayfada:

<textarea data-bind="event: { keyup: $root.GrowTextArea }"></textarea>

Görünüm modelinde:

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

Bu, benim yaptığım gibi bir Knockout foreach tarafından oluşturulmuş birden fazla text alanınız olsa bile çalışmalıdır.


1

Basit Çözüm:

HTML:

<textarea class='expand'></textarea>

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/


1

En basit çözüm:

html:

<textarea class="auto-expand"></textarea>

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

1

Saf JS ile çözüm

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/


1

Bu, kullandığım çözüm. Satır içi bir çözüm istedim ve şu ana kadar bu harika çalışıyor gibi görünüyor:

<textarea onkeyup="$(this).css('height', 'auto').css('height', this.scrollHeight + this.offsetHeight - this.clientHeight);"></textarea>

1

function autoResizeTextarea() {
  for (let index = 0; index < $('textarea').length; index++) {
    let element = $('textarea')[index];
    let offset = element.offsetHeight - element.clientHeight;
    $(element).css('resize', 'none');
    $(element).on('input', function() {
      $(this).height(0).height(this.scrollHeight - offset - parseInt($(this).css('padding-top')));
    });
  }
}

https://codepen.io/nanachi1/pen/rNNKrzQ

bu çalışmalı.


0

@Georgiy Ivankin bir yorumda bir öneride bulundu, başarılı bir şekilde kullandım :) -, ancak küçük değişikliklerle:

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

Maksimum 200 piksel yüksekliğe ulaştıktan sonra genişlemeyi durdurur


0

Eski soru ama bunun gibi bir şey yapabilirsin:

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

Bu şekilde otomatik yeniden boyutlandırma "metin alanı" sınıfına sahip herhangi bir metin alanına uygulanacaktır. Metin kaldırıldığında da küçülür.

jsfiddle:

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


0

Bunu dene:

  $('textarea[name="mytextarea"]').on('input', function(){
    $(this).height('auto').height($(this).prop('scrollHeight') + 'px');
  }).trigger('input');

0

Basit jQuery çözümü:

$("textarea").keyup(function() {
    var scrollHeight = $(this).prop('scrollHeight') - parseInt($(this).css("paddingTop")) - parseInt($(this).css("paddingBottom"));

    if (scrollHeight > $(this).height()) {
        $(this).height(scrollHeight + "px");
    }
});

HTML:

<textarea rows="2" style="padding: 20px; overflow: hidden; resize: none;"></textarea>

Taşma edilmelidir gizli . Yeni boy olan hiçbiri size fare tarafından yeniden boyutlandırılabilir yapmak istemiyorsanız.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.