Автоматическое расширение текстового поля с помощью jQuery


128

Как сделать так, чтобы текстовое поле автоматически расширялось с помощью jQuery?

У меня есть текстовое поле для объяснения повестки дня собрания, поэтому я хочу расширить это текстовое поле, когда текст моей повестки дня будет увеличиваться в этой области текстового поля.


i thik textarea расширяется автоматически.
— Эндрю Салливан

2
возможный дубликат Searching for the Ultimate
— Resizing

Пожалуйста, подумайте об изменении своего вопроса и удалении слова «jQuery»
— vsync

Ответы:


113

Я много пробовал, и этот отличный. Ссылка мертва. Более новая версия доступна здесь . См. Старую версию ниже.
Вы можете попробовать, нажав и удерживая клавишу ввода в текстовом поле. Сравните эффект с другим плагином автоматического расширения текстового поля ....

редактировать на основе комментария

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

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

Чтобы полоса прокрутки в текстовой области не мигала во время расширения / сжатия, вы также можете установить overflowзначение hidden:

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




Обновить:

Ссылка выше не работает. Но вы все равно можете получить здесь файлы javascript .


если мой идентификатор текстового поля - txtMeetingAgenda, то как я могу реализовать свойство Auto textArea в jquery
— Пиюш

здесь событие щелчка определяется или нет
— Пиюш

это все о текстовом поле, но как насчет текстового поля. этот плагин также работает с текстовым полем?
— Пиюш

1
этот плагин не работает, попробуйте
— автоматическое изменение размера

Он отлично работает только одним способом, когда textarea растет. Но когда вы начинаете удалять текст, высота автоматически не уменьшается.
— ekashking

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, вы можете открыть dev con и предоставить более подробную информацию?
— SpYk3HH

1
также требуется, чтобы textarea overflow-y было скрыто, чтобы предотвратить мигание прокрутки
— iulial

2
Если я хочу удалить добавленные строки, увеличенный размер текстового поля останется прежним, возможно ли, что он также может автоматически изменить размер обратно?
— Стивен

33

Увеличивает / уменьшает текстовое поле. В этой демонстрации для привязки событий используется jQuery, но это ни в коем случае не обязательно.
( нет поддержки IE - IE не реагирует на изменение атрибута строк )

ДЕМО СТРАНИЦА


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
потому что код должен немного подождать, пока набранная вами буква будет напечатана внутри текстового поля, и для этого изменит размеры
— текстового поля

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, потому что он заставляет разработчика настраивать код вместо того, чтобы код понимать и адаптироваться к текстовой области,
— vsync

1
Это неверно. Разработчику не нужно настраивать код. Требуется установить высоту 30, и это работает для всего. Пользователь никогда этого не видит. Вот как можно уменьшить текстовое поле. Код действительно понимает текстовое поле и адаптируется к нему. В этом весь смысл.
— drolex 07

Ты прав. демонстрационная страница: 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

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


1
Текстовое поле (я полагаю, текстовый элемент ввода) не является многострочным. Используйте текстовое поле, но оформляйте его соответствующим образом - строки, столбцы и т. Д., А затем используйте плагин автоматического увеличения, как указано выше.
— richsage 01

4

Каждый должен попробовать этот плагин jQuery: xautoresize-jquery . Это действительно хорошо и должно решить вашу проблему.


Это дало мне наилучшие результаты, и его также легко реализовать.
— 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);
    });
});

(Это не будет работать в 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. добавлен перенос слов: break-word для тени, поэтому он разбивается так же, как текстовое поле (принудительные разрывы для очень длинных слов)

Остались некоторые вопросы, касающиеся пробелов. Я не вижу решения для двойных пробелов, они отображаются как одиночные пробелы в тени (рендеринг html). Этого нельзя избежать, используя & nbsp ;, потому что пробелы должны разорваться. Кроме того, текстовое поле разрывает строку после пробела, если для этого места нет места, оно прерывает строку в более ранней точке. Предложения приветствуются.

Исправленный код:

(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 01

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

Для всех, кто использует плагин, опубликованный Рейгелем, имейте в виду, что это отключит функцию отмены в 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'; 
    }
});

Примечание: я заметил, что иногда лучше работает с box-sizing: content-box. Я не совсем уверен, почему он должен правильно обрабатывать отступы :(
— Lodewijk

1

На это есть много ответов, но я нашел что-то очень простое, прикрепил событие keyup к текстовому полю и проверил, что клавиша ввода нажата, код клавиши равен 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 foreach, как это делаю я.



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

@Georgiy Ivankin сделал предложение в комментарии, я успешно его использовал :) -, но с небольшими изменениями:

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