Automatyczne rozszerzanie obszaru tekstowego za pomocą jQuery


Odpowiedzi:


114

Próbowałem wiele i ten jest świetny. Link nie żyje. Nowsza wersja jest dostępna tutaj . Zobacz poniżej starszą wersję.
Możesz spróbować, naciskając i przytrzymując klawisz Enter w obszarze tekstowym. Porównaj efekt z inną automatycznie rozwijającą się wtyczką Textarea ...

edycja na podstawie komentarza

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

uwaga: powinieneś załączyć potrzebne pliki js ...

Aby nie dopuścić do przewijania w textarea z migać i wyłączanie podczas rozszerzania / kurczenia, można ustawić overflow, aby hiddenrównież:

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




Aktualizacja:

Powyższy link jest uszkodzony. Ale nadal możesz pobrać pliki javascript tutaj .


jeśli mój identyfikator pola tekstowego to txtMeetingAgenda, to jak mogę zaimplementować właściwość Auto textArea w jquery
Piyush

tutaj kliknij wydarzenie jest zdefiniowane lub nie
Piyush

to wszystko o textarea, ale co z textbox. czy ta wtyczka działa również dla textbox?
Piyush

1
ta wtyczka nie działa dobrze, spróbuj autosize, jest o wiele lepiej
julesbou

Działa dobrze tylko w jeden sposób, gdy rośnie textarea. Ale kiedy zaczynasz usuwać tekst, nie zmniejsza to automatycznie wysokości.
ekashking

166

Jeśli nie potrzebujesz wtyczki, istnieje bardzo proste rozwiązanie

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

Zobacz, jak działa w jsFiddle. Odpowiadałem tutaj na inne pytanie dotyczące tekstu .

Aby odpowiedzieć na pytanie, czy zrobić to w odwrotnej kolejności lub zmniejszyć po usunięciu tekstu: jsFiddle

A jeśli chcesz mieć wtyczkę

@Jason zaprojektował jeden tutaj


1
Musiałem usunąć + parseFloat ($ (this) .css ("borderTopWidth")) + parseFloat ($ (this) .css ("borderBottomWidth")), w przeciwnym razie nieskończenie
zapętla się

3
Wersja jQuery-less:if (this.clientHeight < this.scrollHeight) { this.style.height = this.scrollHeight + 'px'; }
Georgii Ivankin

3
@metakungfu Cóż, zamiast po prostu głosować w dół, może możesz pomóc poprawić odpowiedź. Nie mam możliwości przetestowania bankomatu Apple Crap, a Safari dla Windows zostało przerwane dawno temu. Więc tak naprawdę nie mogę zrobić nic, aby ustalić, dlaczego to nie zadziała. Pod względem kodu nie ma nic złego w tym rozwiązaniu. Czy na pewno psuje się kod, a nie safari w jsfiddle? safari jest dość wybredne, a skrzypce właśnie przeszły dużą aktualizację. Mayeb, czy możesz otworzyć program dev con i podać więcej szczegółów?
SpYk3HH

1
wymaga również ustawienia przepełnienia textarea-y na ukryte, aby zapobiec
miganiu

2
Jeśli chcę usunąć dodane wiersze, powiększony rozmiar pola tekstowego pozostaje taki sam, czy jest możliwe, że może ono również automatycznie zmienić rozmiar z powrotem?
Steven

33

Powiększa / zmniejsza obszar tekstu. To demo wykorzystuje jQuery do wiązania zdarzeń, ale nie jest to w żaden sposób konieczne.
( brak obsługi IE - IE nie reaguje na zmianę atrybutów wierszy )

STRONA DEMO


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 (zaktualizowany)

$(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
ponieważ kod musi trochę poczekać, aż wpisana litera zostanie wydrukowana w obszarze tekstowym, a tym samym zmienić wymiary
obszaru tekstu

1
Widzę, rozwiązanie jest zepsute, gdy tekst jest kopiowany (CTRL + V) z dowolnego źródła. Natomiast jeśli tekst jest wpisywany ręcznie - jest to niesamowite i bardzo płynne.
Satya Kalluri

1
@vsync: jak zmodyfikowałbyś wiele obszarów tekstowych? To znaczy masz textarea1 i textarea2 i chcesz, aby oba rosły?
jmoreno

1
To powinna być najlepsza odpowiedź!
Wysłałem

1
@AllyMurray - poszedłem teraz i zaktualizowałem go do 16, ponieważ wydaje się, że daje lepszy wynik. i tak, to jest oczekiwana wysokość linii
vsync


21

Możesz spróbować tego

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


1
jeśli chcesz uzyskać scrollHeight z $ (this), możesz użyć $ (this) .prop ('scrollHeight'); zamiast tego;)
Samuel Vicent

4
miga przy każdym przełamaniu wiersza
joe

11

Dzięki SpYk3HH zacząłem od jego rozwiązania i przekształciłem je w to rozwiązanie, które dodaje kurczącą się funkcjonalność i jest jeszcze prostsze i szybsze, jak przypuszczam.

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

Przetestowano w aktualnej przeglądarce Chrome, Firefox i Android 2.3.3.

W niektórych przeglądarkach mogą być widoczne migające paski przewijania. Dodaj ten CSS, aby rozwiązać ten problem.

textarea{ overflow:hidden; }

w ogóle nie działa dobrze: / każdy wpisywany znak dodaje wysokość.
vsync,

1
U mnie działa idealnie! Z pewnością w prostym kodzie nie ma nic do zrobienia tego, co mówisz, że robi.
drolex

1
tak, widzę to teraz, twój kod musi mieć linię, która początkowo ustawia wysokość na 30. jest to prawdopodobnie niepotrzebny ilne, ponieważ zmusza programistę do poprawiania kodu, zamiast kodu rozumieć i dostosowywać się do obszaru
tekstowego

1
To jest niepoprawne. Deweloper nie musi modyfikować kodu. Wymagane jest ustawienie wysokości na 30 i działa do wszystkiego. Użytkownik nigdy tego nie widzi. W ten sposób jest w stanie zmniejszyć obszar tekstu. Kod rozumie i dostosowuje się do obszaru tekstu. O to chodzi.
drolex

Masz rację. strona demonstracyjna: jsbin.com/ObEcoza/2/edit (ustawienie wysokości 1pxwydaje się być lepsze)
vsync

10

Aby zdefiniować automatycznie rozwijany obszar tekstowy, musisz zrobić dwie rzeczy:

  1. Rozwiń go po kliknięciu w nim klawisza Enter lub wpisz zawartość więcej niż jednej linii.
  2. I zmniejsz go, aby uzyskać rzeczywisty rozmiar, jeśli użytkownik wprowadził białe spacje. ( Bonus )

Oto ręczna funkcja do wykonania zadania.

Działa dobrze z prawie wszystkimi przeglądarkami (<IE7) . Oto metoda:

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

TUTAJ jest post na ten temat.


6

Użyłem Textarea Expander plugin jQuery wcześniej z dobrymi wynikami.


1
Pole tekstowe (zakładam, że element tekstu wejściowego) nie jest wielowierszowe. Użyj obszaru tekstowego, ale odpowiednio go stylizuj - wiersze, kolumny itp., A następnie użyj wtyczki automatycznego wzrostu, jak powyżej.
richsage

4

Każdy powinien wypróbować tę wtyczkę jQuery: xautoresize-jquery . To jest naprawdę dobre i powinno rozwiązać twój problem.


Ten dał mi najlepsze wyniki i jest również łatwy do wdrożenia.
blitzkid

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

(To nie zadziała w przeglądarce Internet Explorer 9 lub starszej, ponieważ korzysta ze inputzdarzenia)


w moim projekcie, ponieważ renderuję całe rzeczy na stronie za pomocą JQuery i maszynopisu, twoje rozwiązanie było jedynym sposobem, w jaki mogłem rozwiązać swój problem dzięki
Harry Sarshogh Kwietnia

3

Właśnie zbudowałem tę funkcję, aby rozszerzać obszary tekstowe podczas ładowania strony. Po prostu zmień eachna, keyupa nastąpi to po wpisaniu pola tekstowego.

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

Przetestowano w Chrome, IE9 i Firefox. Niestety Firefox ma ten błąd, który zwraca nieprawidłową wartość dla scrollHeight, więc powyższy kod zawiera (hacky) obejście tego problemu.


3

Naprawiłem kilka błędów w odpowiedzi udzielonej przez Reigel (zaakceptowana odpowiedź):

  1. Kolejność, w jakiej są zastępowane jednostki HTML, nie powoduje teraz nieoczekiwanego kodu w elemencie shadow. (Oryginał zastąpiony „>” przez „& ampgt;”, co w rzadkich przypadkach powoduje nieprawidłowe obliczenie wysokości).
  2. Jeśli tekst kończy się znakiem nowej linii, cień otrzymuje teraz dodatkowy znak „#” zamiast stałej wysokości dodanej, jak ma to miejsce w oryginale.
  3. Zmiana rozmiaru obszaru tekstu po inicjalizacji powoduje zaktualizowanie szerokości cienia.
  4. dodany zawijanie słów: słowo łamane dla cienia, więc łamie to samo, co obszar tekstowy (wymuszanie przerw w bardzo długich słowach)

Pozostało jeszcze kilka kwestii dotyczących przestrzeni. Nie widzę rozwiązania dla podwójnych spacji, są one wyświetlane jako pojedyncze spacje w cieniu (renderowanie html). Nie można tego usunąć za pomocą & nbsp;, ponieważ spacje powinny zostać przerwane. Ponadto obszar tekstowy przerywa linię po spacji, jeśli nie ma miejsca na tę przestrzeń, przerywa linię we wcześniejszym punkcie. Sugestie są mile widziane.

Poprawiony 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

Kod SpYk3HH z dodatkiem do zmniejszania rozmiaru.

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

Widziałeś moją odpowiedź przed swoją?
drolex

1
Twoje rozwiązanie mi nie odpowiada, wystąpił błąd, nie pamiętam który.
DSblizzard

3

To działało lepiej dla mnie:

$('.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

Wydaje się, że ludzie mają bardzo przepracowane rozwiązania ...

Oto jak to robię:

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

To zadziała z długimi liniami, jak również z przerwami w liniach .. rośnie i kurczy się ..


1

Napisałem tę funkcję jquery, która wydaje się działać.

Musisz jednak podać minimalną wysokość w css i jeśli nie chcesz kodować, musi mieć dwie cyfry. tj. 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

Każdy, kto korzysta z wtyczki opublikowanej przez Reigel, musi mieć świadomość, że spowoduje to wyłączenie funkcji cofania w przeglądarce Internet Explorer (przejdź do wersji demonstracyjnej).

Jeśli jest to dla Ciebie problem, sugerowałbym zamiast tego użycie wtyczki opublikowanej przez @richsage, ponieważ nie cierpi na ten problem. Aby uzyskać więcej informacji, zapoznaj się z drugim podpunktem w temacie Wyszukiwanie ostatecznego obszaru tekstowego zmiany rozmiaru .



1

Chciałem animacji i automatycznego zmniejszania. Połączenie jest najwyraźniej trudne, ponieważ ludzie wymyślili dla niego dość intensywne rozwiązania. Uczyniłem go również odpornym na wiele tekstów. I nie jest tak absurdalnie ciężki jak wtyczka jQuery.

Oparłem się na odpowiedzi vsync (i ulepszeniu, które dla niej wprowadził), http://codepen.io/anon/pen/vlIwj jest kodem dla mojego ulepszenia.

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

Uwaga: zauważyłem, że czasami działa lepiej w przypadku rozmiaru pudełka: pole zawartości. Nie jestem jednak do końca pewien, dlaczego powinien poprawnie przetwarzać wypełnienie :(
Lodewijk,

1

Odpowiedzi na to jest wiele, ale znalazłem coś bardzo prostego, dołącz zdarzenie keyup do obszaru tekstowego i sprawdź, czy klawisz enter, naciśnij kod klucza to 13

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

Spowoduje to dodanie kolejnego wiersza do obszaru tekstu i możesz dostosować szerokość za pomocą CSS.


1

Powiedzmy, że próbujesz to osiągnąć za pomocą Knockout ... oto jak:

Na stronie:

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

W widoku modelu:

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

Powinno to działać, nawet jeśli masz wiele obszarów tekstu utworzonych przez Knockout foreach, tak jak ja.


1

Proste rozwiązanie:

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

Najprostsze rozwiązanie:

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

Rozwiązanie z czystym 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/


1

To jest rozwiązanie, z którego korzystałem. Chciałem rozwiązania inline i jak dotąd wydaje się, że działa świetnie:

<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

to powinno działać.


1

to działało dla mnie doskonale

 $(".textarea").on("keyup input", function(){
            $(this).css('height', 'auto').css('height', this.scrollHeight+ 
       (this.offsetHeight - this.clientHeight));
   });

0

@Georgiy Ivankin zasugerował w komentarzu, skorzystałem z niego pomyślnie :) - ale z niewielkimi zmianami:

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

Przestaje się rozwijać po osiągnięciu maksymalnej wysokości 200 pikseli


0

Stare pytanie, ale możesz zrobić coś takiego:

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

W ten sposób automatyczna zmiana rozmiaru zostanie zastosowana do dowolnego obszaru tekstowego z klasą „tekst-obszar”. Zmniejsza się również po usunięciu tekstu.

jsfiddle:

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


0

Spróbuj tego:

  $('textarea[name="mytextarea"]').on('input', function(){
    $(this).height('auto').height($(this).prop('scrollHeight') + 'px');
  }).trigger('input');
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.