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

128

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

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

Piyush
источник
i thik textarea расширяется автоматически.
Эндрю Салливан
2
возможный дубликат Searching for the Ultimate
Resizing
Пожалуйста, подумайте об изменении своего вопроса и удалении слова «jQuery»
vsync

Ответы:

113

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

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

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

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

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

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




Обновить:

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

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

SpYk3HH
источник
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;
    });
VSync
источник
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>

reza.cse08
источник
если вы хотите получить 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; }
drolex
источник
это совсем не работает: каждый символ, который я набираю, добавляет высоту.
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 с хорошими результатами.

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

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

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

benrwb
источник
в моем проекте, поскольку я визуализирую все на странице с помощью 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;
        };
    }
});
DSblizzard
источник
Вы видели мой ответ раньше своего?
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, поскольку он не страдает от этой проблемы. Дополнительную информацию см. Во втором пункте о поиске текстовой области максимального изменения размера .

user1018494
источник
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'; 
    }
});
Lodewijk
источник
Примечание: я заметил, что иногда лучше работает с 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='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

Самое простое решение:

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/

samb102
источник
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

это должно работать.

nanachi1
источник
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 пикселей.

davidman77
источник
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/

rotaercz
источник
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>

Перелив нужно скрыть . Изменение размер не является ни , если вы не хотитечтобы сделать его изменяемымпомощью мыши.

elano7
источник