Автоматичне розширення текстової області за допомогою jQuery


128

Як я можу змусити текстову область автоматично розширюватися за допомогою jQuery?

У мене є текстове поле для пояснення порядку денного засідання, тому я хочу розгорнути це поле, коли текст мого порядку денного постійно зростає в цій області.


i thik textarea автоматично розширюється.
andrew Sullivan


Будь ласка, подумайте про те, щоб змінити своє питання та видалити слово "jQuery"
vsync

Відповіді:


113

Я пробував багато, і це чудово. Посилання мертва. Більш нова версія доступна тут . Дивіться старішу версію нижче.
Ви можете спробувати, натиснувши і утримуючи клавішу введення в текстовій області. Порівняйте ефект з іншими автоматично розширюваними плагінами textarea ....

редагувати на основі коментаря

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

Примітка: ви повинні включити необхідні файли js ...

Для запобігання прокрутки в текстовому полі з мерехтіти і вимикання під час розширення / стиснення, ви можете встановити overflowдо , hiddenа також:

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




Оновлення:

Посилання вище перервано. Але ви все одно можете отримати тут файли javascript .


якщо мій ідентифікатор текстового поля txtMeetingAgenda, то як я можу реалізувати властивість Auto textArea в jquery
Piyush

тут подія натискання визначена чи ні
Піюш

це все про textarea, але як щодо textbox.is цей плагін також працює для textbox?
Піюш

1
цей плагін не працює добре, спробуйте автоматизувати, це набагато краще
julesbou

Це добре працює лише одним способом, коли текстареа розростається. Але коли ви починаєте видаляти текст, висота не зменшується автоматично.
екшакінг

166

Якщо ви не хочете плагін, є дуже просте рішення

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

Дивіться, як це працює у jsFiddle, який я використовував для відповіді на інше текстове запитання тут .

Щоб відповісти на запитання про те, як зробити це в зворотному порядку або зменшити його в міру видалення тексту: jsFiddle

А якщо ви хочете плагін

@Jason створив тут один


1
Мені довелося видалити + parseFloat ($ (this) .css ("borderTopWidth")) + parseFloat ($ (this) .css ("borderBottomWidth")), інакше це нескінченно
циклічне текстові області,

3
версія без jQuery:if (this.clientHeight < this.scrollHeight) { this.style.height = this.scrollHeight + 'px'; }
Георгій Іванкін

3
@metakungfu Ну, а не просто зволікати, можливо, ви можете допомогти покращити відповідь. У мене немає ніякого способу тестування яблучних лайм-атмів і сафарі для Windows було припинено давно. Тому я реально нічого не можу визначити, чому це не вийде. З точки зору коду, в цьому рішенні немає нічого поганого. Ви впевнені, що код зламається, а не сафарі, який порушує jsfiddle? safari досить вибагливий, і загадка просто пройшла через основне оновлення. Mayeb, ви можете відкрити розробник і надати детальніше?
SpYk3HH

1
також потрібно textarea overflow-y встановити на прихований, щоб запобігти миготіння прокрутки
липня

2
Якщо я хочу видалити додані рядки, збільшений розмір текстового поля залишається колишнім, чи можливо він також може автоматично змінити розмір назад?
Стівен

33

Росте / скорочується textarea. Ця демонстрація використовує jQuery для прив'язки подій, але це не обов'язково.
( немає підтримки IE - IE не відповідає на зміну атрибутів рядків )

DEMO PAGE


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 (оновлено)

$(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
тому що код повинен трохи почекати, щоб лист, який ви ввели, буде надрукований у текстовій області, а потім змінити розміри textarea
vsync

1
Я бачу, рішення розбивається, коли текст копіюється (CTRL + V) з будь-якого джерела. Хоча, якщо текст вводиться вручну - це приголомшливо і дуже гладко.
Сатья Каллурі

1
@vsync: як би ви змінили для кількох текстових областей? Тобто у вас є textarea1 і textarea2 і ви хочете дозволити обом рости?
jmoreno

1
Це має бути головна відповідь! Я відповідав на питання , заснований на тому , що якщо кому - то цікаво: stackoverflow.com/questions/29930300 / ...
gsamaras

1
@AllyMurray - я пішов зараз і оновив його до 16, оскільки, здається, дає кращий результат. і так, це очікувана висота лінії
vsync


20

Ви можете спробувати це

$('#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), ви можете використовувати $ (this) .prop ('scrollHeight'); натомість;)
Самуель Вікент

3
він блимає кожен розрив рядка
Джо

11

Завдяки SpYk3HH я почав з його рішення і перетворив його на це рішення, яке додає функціональність, що скорочується, і ще простіше і швидше, я вважаю.

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

Тестовано в поточних браузерах Chrome, Firefox та Android 2.3.3.

У деяких браузерах ви можете побачити спалахи смуг прокрутки. Додайте цей CSS, щоб вирішити це.

textarea{ overflow:hidden; }

це зовсім не добре: / кожен тип персонажа я додає висоти.
vsync

1
Це прекрасно працює для мене! У простому коді точно немає нічого, що можна зробити, як ти кажеш, це робить.
drolex

1
так, я бачу це зараз, у вашому коді повинен бути рядок, який встановлює висоту спочатку 30. це, мабуть, не потрібна ilne, оскільки вона змушує розробника налаштувати код, а не код зрозуміти та адаптуватись до textarea,
vsync

1
Це неправильно. Розробнику не потрібно підробляти код. Встановити висоту в 30 потрібно, і вона працює на все. Користувач ніколи не бачить, щоб це сталося. Ось так воно здатне скоротити текстиль. Код розуміє та адаптується до текстової області. У цьому вся суть.
drolex

Ви праві. демонстраційна сторінка: jsbin.com/ObEcoza/2/edit (встановлення висоти, 1pxздається, краще)
vsync

10

Щоб визначити автоматичну текстову область, що розширюється, вам потрібно зробити дві речі:

  1. Розгорніть його, натиснувши клавішу Enter всередині нього або введіть вміст більше одного рядка.
  2. І зменшіть його при розмитті, щоб отримати фактичний розмір, якщо користувач ввів пробіли. ( Бонус )

Ось функція ручної роботи для виконання завдання.

Відмінно працює майже з усім браузером (<IE7) . Ось метод:

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

ТУТ - пост про це.


6

Раніше я використовував плагін Textarea Expander jQuery з хорошими результатами.


1
Текстове поле (вхідний текстовий елемент, який я вважаю) не є багаторядковим. Використовуйте textarea, але стилі його належним чином - рядки, стовпці тощо, а потім використовуйте плагін для автоматичного зростання, як зазначено вище.
богатир

4

Кожен повинен спробувати цей плагін jQuery: xautoresize-jquery . Це дійсно добре і повинно вирішити вашу проблему.


Цей дав мені найкращі результати, а також його легко здійснити.
блицкід

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

(Це не буде працювати в Internet Explorer 9 або старшої версії, оскільки він використовує inputподію)


у моєму проекті, коли я перекладаю цілі речі на сторінці за допомогою Jquery та машинопису, ваше рішення було єдиним способом, що я міг вирішити свою проблему завдяки
Гаррі Саршо

3

Я просто побудував цю функцію для розширення текстових областей при завантаженні сторінки. Просто змініть eachна, keyupі це відбудеться при введенні текстової області.

// 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 та Firefox. На жаль, у Firefox є ця помилка, яка повертає невірне значення для scrollHeight, тому вищевказаний код містить (хакі) спосіб вирішення.


3

Я виправив кілька помилок у відповіді, наданій Рейгелем (прийнята відповідь):

  1. Порядок, в якому замінюються об'єкти html зараз, не викликає несподіваного коду в тіньовому елементі. (Оригінал замінив ">" на "& ampgt;", викликаючи неправильний розрахунок висоти в деяких рідкісних випадках).
  2. Якщо текст закінчується новим рядком, тінь тепер отримує додатковий символ "#", замість того, щоб мати фіксовану додану висоту, як це має місце в оригіналі.
  3. Змінення розміру текстової області після ініціалізації актуалізує ширину тіні.
  4. додано обгортання слів: слово розбиття для тіні, тож воно порушує те саме, що і текстареа (змушує перерви на дуже довгі слова)

Залишилося кілька питань, що стосуються пробілів. Я не бачу рішення для подвійних пробілів, вони відображаються як одиничні пробіли в тіні (html-рендерінг). Це неможливо вирішити за допомогою & nbsp ;, тому що пробіли повинні бути розбиті. Крім того, textarea розриває лінію після пробілу, якщо для цього простору немає місця, вона перерве лінію в більш ранній точці. Пропозиції вітаються.

Виправлений код:

(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

Код SpYk3HH з додаванням для зменшення розміру.

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

Ви бачили мою відповідь перед вашою?
drolex

1
Ваше рішення мене не влаштовує, була якась помилка, я не пам’ятаю, яка.
DSblizzard

2

Це працювало для мене краще:

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

Люди, здається, мають надто відпрацьовані рішення ...

Ось як я це роблю:

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

Це буде працювати з довгими лініями, а також з розривами ліній .. зростає і скорочується ..


1

Я написав цю функцію jquery, яка, здається, працює.

Потрібно вказати мінімальну висоту в css, і якщо ви не хочете зробити якесь кодування, воно повинно мати дві цифри. тобто 12 пікселів;

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

Для всіх, хто використовує плагін, опублікований Reigel, будь ласка, майте на увазі, що це відключить функцію скасування в Internet Explorer (ідіть, демонструйте демонстрацію).

Якщо це проблема для вас, то я б запропонував використати плагін, опублікований @richsage, оскільки він не страждає від цієї проблеми. Додаткову інформацію див. У другій точці пункту " Пошук остаточного розміру текстової області" .



1

Мені хотілося анімації та автоматичного скорочення. Поєднання, мабуть, важке, тому що люди придумали досить інтенсивні рішення для нього. Я також зробив його багатотекстовим. І це не так смішно важко, як плагін jQuery.

Я грунтувався на відповіді vsync (і поліпшенні, які він зробив для цього), http://codepen.io/anon/pen/vlIwj - це кодек для мого вдосконалення.

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

Примітка: я помітив, що іноді краще спрацьовує з розміром вікна: content-box. Я не зовсім впевнений, чому все-таки слід правильно обробити прокладку :(
Lodewijk

1

На це є багато відповідей, але я знайшов щось дуже просте, приєднайте подію клавіатури до текстової області та перевірте наявність клавіші введення, натисніть клавішу, код 13

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

Це додасть ще один рядок текстовій області, і ви можете стилізувати ширину за допомогою CSS.


1

Скажімо, ви намагаєтеся досягти цього за допомогою Knockout ... ось як:

На сторінці:

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

У моделі перегляду:

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

Це має спрацювати, навіть якщо у вас є кілька текстових областей, створених інструментом Knockout, як я.



1

Найпростіше рішення:

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

Розчин з чистим 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

Це рішення, яке я закінчив використовувати. Я хотів вбудованого рішення, і це поки що, здається, працює чудово:

<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

це має працювати.


0

@ Георгій Іванкін зробив пропозицію в коментарі, я її успішно використав :) - але з незначними змінами:

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

Він припиняє розширюватися після досягнення максимальної висоти 200 пікселів


0

Старе питання, але ви можете зробити щось подібне:

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

Таким чином автоматичний розмір застосовуватиметься до будь-яких текстових областей із класом "текстова область". Також стискається при видаленні тексту.

jsfiddle:

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


0

Спробуйте це:

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

0

Просте рішення jQuery:

$("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>

Переповнення слід приховати . Зміни розміру - це жодне, якщо ви не хочете робити його зміною за допомогою миші.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.