Создание текстового поля с автоматическим изменением размера

Был еще одна ветка об этом, который я пробовал. Но есть одна проблема: textarea не сжимается при удалении содержимого. Я не могу найти способ уменьшить его до правильного размера - значение clientHeight возвращается как полный размер textarea, а не его содержимое.

Код с этой страницы приведен ниже:

function FitToContent(id, maxHeight)
{
   var text = id && id.style ? id : document.getElementById(id);
   if ( !text )
      return;

   var adjustedHeight = text.clientHeight;
   if ( !maxHeight || maxHeight > adjustedHeight )
   {
      adjustedHeight = Math.max(text.scrollHeight, adjustedHeight);
      if ( maxHeight )
         adjustedHeight = Math.min(maxHeight, adjustedHeight);
      if ( adjustedHeight > text.clientHeight )
         text.style.height = adjustedHeight + "px";
   }
}

window.onload = function() {
    document.getElementById("ta").onkeyup = function() {
      FitToContent( this, 500 )
    };
}

Принятый ответ для темы, которую вы связали, работает для меня. Добавление разрывов строк расширяет текстовое поле, а удаление их сжимает текстовую область. Какой браузер вы используете?

EndangeredMassa 18.01.2009 02:07

Моя функция делает ошибку. Обязательно вводить новую строку в конце строки. Это лучшее решение. james.padolsey.com/javascript/jquery-plugin-autoresize

user663464 17.03.2011 03:06

возможный дубликат Автоматическое изменение размера текстового поля с использованием прототипа

Ciro Santilli新疆棉花TRUMP BAN BAD 27.08.2014 18:28

Вы можете попробовать мой плагин для этого: github.com/AndrewDryga/jQuery.Textarea.Autoresize

Andrew Dryga 14.06.2013 19:48

Я создал для этого пакет, если вы используете реакцию: npmjs.com/package/react-fluid-textarea

Martin Dawson 03.12.2017 03:08

Сортировка и сладкий ответ здесь: stackoverflow.com/a/995374/5114465function textAreaAdjust(o) { o.style.height = "1px"; o.style.height = (25+o.scrollHeight)+"px"; } <textarea onkeyup = "textAreaAdjust(this)" style = "overflow:hidden"></textarea>

Shurvir Mori 04.01.2020 15:06
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
В настоящее время производительность загрузки веб-сайта имеет решающее значение не только для удобства пользователей, но и для ранжирования в...
Безумие обратных вызовов в javascript [JS]
Безумие обратных вызовов в javascript [JS]
Здравствуйте! Юный падаван 🚀. Присоединяйся ко мне, чтобы разобраться в одной из самых запутанных концепций, когда вы начинаете изучать мир...
Система управления парковками с использованием HTML, CSS и JavaScript
Система управления парковками с использованием HTML, CSS и JavaScript
Веб-сайт по управлению парковками был создан с использованием HTML, CSS и JavaScript. Это простой сайт, ничего вычурного. Основная цель -...
JavaScript Вопросы с множественным выбором и ответы
JavaScript Вопросы с множественным выбором и ответы
Если вы ищете платформу, которая предоставляет вам бесплатный тест JavaScript MCQ (Multiple Choice Questions With Answers) для оценки ваших знаний,...
407
6
480 249
44
Перейти к ответу Данный вопрос помечен как решенный

Ответы 44

Вы используете более высокое значение текущего clientHeight и scrollHeight содержимого. Когда вы уменьшаете scrollHeight путем удаления содержимого, вычисляемая область не может уменьшаться, потому что clientHeight, ранее установленный style.height, удерживает ее открытой. Вместо этого вы можете взять max () scrollHeight и минимальное значение высоты, которое вы предварительно определили или рассчитали из textarea.rows.

В общем, вам, вероятно, не стоит полагаться на scrollHeight в элементах управления формой. Кроме того, что scrollHeight традиционно менее широко поддерживается, чем некоторые другие расширения IE, HTML / CSS ничего не говорит о том, как элементы управления формы реализованы внутри, и вам не гарантируется, что scrollHeight будет иметь что-то значимое. (Традиционно некоторые браузеры использовали для этой задачи виджеты ОС, что делало взаимодействие CSS и DOM на их внутреннем устройстве невозможным.) По крайней мере, понюхайте наличие scrollHeight / clientHeight, прежде чем пытаться включить эффект.

Другой возможный альтернативный подход, позволяющий избежать этой проблемы, если важно, чтобы он работал более широко, может заключаться в использовании скрытого блока div с той же шириной, что и текстовое поле, и с тем же шрифтом. При нажатии клавиши вы копируете текст из текстового поля в текстовый узел в скрытом div (не забывая заменить '\ n' разрывом строки и правильно экранировать '<' / '&', если вы используете innerHTML). Затем простое измерение offsetHeight div даст вам нужную высоту.

Какие браузеры должны иметь проблемы с scrollHeight для текстовых полей? Прекрасно работает с текущими версиями IE, Firefox и Opera ...

Christoph 18.01.2009 12:54

Единственное, что у меня есть, - это Konqueror, который возвращает clientHeight как scrollHeight. Это поведение, которого вы можете ожидать, если браузер не применяет блочную модель CSS к внутренним компонентам виджетов, что они не всегда делали, и стандарт не говорит, что они должны.

bobince 18.01.2009 15:38

Я тестировал скрипт в обычных браузерах, и он не удался в Chrome и Safari. Это из-за постоянно обновляемой переменной scrollHeight.

Я применил скрипт DisgruntledGoat с помощью jQuery и добавил исправление хрома.

function fitToContent(/* JQuery */text, /* Number */maxHeight) {
    var adjustedHeight = text.height();
    var relative_error = parseInt(text.attr('relative_error'));
    if (!maxHeight || maxHeight > adjustedHeight) {
        adjustedHeight = Math.max(text[0].scrollHeight, adjustedHeight);
        if (maxHeight)
            adjustedHeight = Math.min(maxHeight, adjustedHeight);
        if ((adjustedHeight - relative_error) > text.height()) {
            text.css('height', (adjustedHeight - relative_error) + "px");
            // chrome fix
            if (text[0].scrollHeight != adjustedHeight) {
                var relative = text[0].scrollHeight - adjustedHeight;
                if (relative_error != relative) {
                    text.attr('relative_error', relative + relative_error);
                }
            }
        }
    }
}

function autoResizeText(/* Number */maxHeight) {
    var resize = function() {
        fitToContent($(this), maxHeight);
    };
    $("textarea").attr('relative_error', 0);
    $("textarea").each(resize);
    $("textarea").keyup(resize).keydown(resize);
}

Если scrollHeight можно доверять, то:

textarea.onkeyup=function() {
  this.style.height='';
  this.rows=this.value.split('\n').length;
  this.style.height=this.scrollHeight+'px';
}

this.rows = this.value.split ('\ n'). length; Это не сработает. Потому что количество строк в тексте не равно количеству \ n. Вы не рассматривали перенос текста.

Eastern Monk 13.03.2012 21:44

@EasternMonk, если вы попробуете, он действительно работает хорошо и довольно интуитивно понятен ИМХО: jsbin.com/tilokafasa/1/edit?html,js,output

localhostdotdev 09.05.2019 18:57
$('textarea').bind('keyup change', function() {
    var $this = $(this), $offset = this.offsetHeight;
    $offset > $this.height() && $offset < 300 ?
        $this.css('height ', $offset)
            .attr('rows', $this.val().split('\n').length)
            .css({'height' : $this.attr('scrollHeight'),'overflow' : 'hidden'}) :
        $this.css('overflow','auto');
});
Ответ принят как подходящий

Это работает для меня (Firefox 3.6 / 4.0 и Chrome 10/11):

var observe;
if (window.attachEvent) {
    observe = function (element, event, handler) {
        element.attachEvent('on'+event, handler);
    };
}
else {
    observe = function (element, event, handler) {
        element.addEventListener(event, handler, false);
    };
}
function init () {
    var text = document.getElementById('text');
    function resize () {
        text.style.height = 'auto';
        text.style.height = text.scrollHeight+'px';
    }
    /* 0-timeout to get the already changed text */
    function delayedResize () {
        window.setTimeout(resize, 0);
    }
    observe(text, 'change',  resize);
    observe(text, 'cut',     delayedResize);
    observe(text, 'paste',   delayedResize);
    observe(text, 'drop',    delayedResize);
    observe(text, 'keydown', delayedResize);

    text.focus();
    text.select();
    resize();
}
textarea {
    border: 0 none white;
    overflow: hidden;
    padding: 0;
    outline: none;
    background-color: #D0D0D0;
}
<body onload = "init();">
<textarea rows = "1" style = "height:1em;" id = "text"></textarea>
</body>

Если хотите, попробуйте на jsfiddle Он начинается с одной строки и увеличивается только на необходимое количество. Это нормально для одного textarea, но я хотел написать что-то, где у меня было бы много-много-много таких textarea (примерно столько, сколько обычно бывает строк в большом текстовом документе). В этом случае это действительно медленно. (В Firefox это безумно медленно.) Так что мне действительно нужен подход, использующий чистый CSS. Это было бы возможно с contenteditable, но я хочу, чтобы это был только открытый текст.

К сожалению, в IE8 это не работает, и поскольку он использует overflow: hidden, у пользователей IE нет запасного плана. Вы можете включить или выключить переполнение, чтобы решить эту проблему, но тогда полоса прокрутки теряет свой смысл. Если вы не используете overflow: hidden, текстовое поле не сжимается. Но близко!

Chris Moschini 10.05.2011 10:14

@ChrisMoschini Я немного изменил код. Это работает для вас?

panzi 10.05.2011 20:02

Используя тестер IE, приведенный выше код работает даже с IE 5.5. Я не тестировал IE 9, потому что в моем VirtualBox установлена ​​только XP.

panzi 10.05.2011 22:42

Оно делает! Сделал для вас jsfiddle: jsfiddle.net/CbqFv Теперь он работает в Chrome, Firefox и IE8 - хотя в IE8 он немного глючит. Когда вы увеличиваете или уменьшаете количество строк, это немного пугает. Как вы могли видеть в плагине автоизменения размера для jQuery, они работают над этим, клонируя текстовое поле, устанавливая его высоту на auto вместо оригинала, а затем используя это, чтобы установить высоту прокрутки на оригинале. Я сделал это в этой обновленной скрипке: jsfiddle.net/CbqFv/2 Это решает проблему IE, но Firefox перестает работать.

Chris Moschini 10.05.2011 22:58

Привет, Панзи, все отлично работает. Но есть ли способ заставить эту работу работать с несколькими текстовыми полями на одной странице?

Helen Neely 08.02.2012 15:13

@HelenNeely: Да, просто примените его ко всем текстовым полям.

panzi 18.02.2012 06:48

Спасибо, но я вижу, что он использует id = 'text' для поиска DOM. Но я не могу использовать один и тот же идентификатор для нескольких текстовых полей, так как мне изменить его на класс, который могут использовать другие? Еще раз спасибо.

Helen Neely 18.02.2012 12:45

@HelenNeely: Тогда не используйте идентификатор. Например. использовать класс и делать то, что init делает для всех элементов этого класса. Это должно быть задание для новичков.

panzi 23.02.2012 08:28

Если вы хотите настроить таргетинг на современные браузеры, вам не нужно прикреплять обработчик ко всем этим событиям. Просто прикрепите к событию input или oninput.

Denilson Sá Maia 20.09.2012 22:40

@ DenilsonSá Если бы можно было предположить, что используются только современные браузеры, Интернет был бы лучшим местом.

panzi 22.09.2012 05:52

Работает ли это, если у меня есть несколько текстовых полей, для которых требуется эта функция?

user3388884 27.03.2014 00:39

Это не сработает, если в IE11 есть полоса прокрутки. Если вы используете эту скрипку jsfiddle.net/CbqFv и вводите строки, пока у вас не появится полоса прокрутки, вы ее увидите. Любые идеи?

kaljak 25.08.2015 16:05

kaljak, помогает ли добавление overflow: hidden;? Обновлено: подождите, это уже есть. Тогда понятия не имею.

panzi 25.08.2015 17:37

Что я могу сделать, чтобы полоса прокрутки не мигала? Если стиль overflow:auto;

ollazarev 09.04.2016 02:12

@ollazarev Может быть, использовать visibility:hidden;position:fixed; textarea / div для измерения высоты? Или используйте contentEditable = "true"-div вместо текстового поля (что сильно усложняет другие вещи).

panzi 09.04.2016 22:02

Это полностью нарушается, если текстовое поле находится рядом с нижним концом страницы - все прыгает назад и вперед из-за style.height='auto'. Я подозреваю, что решение состоит в том, чтобы добавить скрытого родственника, используемого только для измерения.

rr- 12.06.2016 12:03

будет ли он зависать в браузере, если вставить большой текст внутрь, например, файл размером 3 МБ, после загрузки и получения ответа обратно в текстовое поле

Reborn 11.09.2019 13:28

В Firefox 70 размер первого переполненного символа не изменяется. На втором символе он изменяется.

cdalxndr 03.12.2019 00:15

Это отлично работает с JSFuddle, но мне интересно (поскольку у меня есть такая задача), как он себя ведет, если вы увеличиваете и уменьшаете размер шрифта в настройках браузера. Также на разных языках?

Vladyn 28.05.2020 10:54

rows = 1 решил мою проблему

Supun Kavinda 17.02.2021 09:19

Немного исправлений. Отлично работает в Opera

  $('textarea').bind('keyup keypress', function() {
      $(this).height('');
      var brCount = this.value.split('\n').length;
      this.rows = brCount+1; //++ To remove twitching
      var areaH = this.scrollHeight,
          lineHeight = $(this).css('line-height').replace('px',''),
          calcRows = Math.floor(areaH/lineHeight);
      this.rows = calcRows;
  });

работает до тех пор, пока ваши строки не переполняются - тогда они не поместятся.

Tomáš Kafka 14.10.2011 19:11

Я использовал следующий код для нескольких текстовых полей. Работает нормально в Chrome 12, Firefox 5 и IE 9, даже при удалении, вырезании и вставке действий, выполняемых в текстовых областях.

function attachAutoResizeEvents() {
  for (i = 1; i <= 4; i++) {
    var txtX = document.getElementById('txt' + i)
    var minH = txtX.style.height.substr(0, txtX.style.height.indexOf('px'))
    txtX.onchange = new Function("resize(this," + minH + ")")
    txtX.onkeyup = new Function("resize(this," + minH + ")")
    txtX.onchange(txtX, minH)
  }
}

function resize(txtX, minH) {
  txtX.style.height = 'auto' // required when delete, cut or paste is performed
  txtX.style.height = txtX.scrollHeight + 'px'
  if (txtX.scrollHeight <= minH)
    txtX.style.height = minH + 'px'
}
window.onload = attachAutoResizeEvents
textarea {
  border: 0 none;
  overflow: hidden;
  outline: none;
  background-color: #eee
}
<textarea style='height:100px;font-family:arial' id = "txt1"></textarea>
<textarea style='height:125px;font-family:arial' id = "txt2"></textarea>
<textarea style='height:150px;font-family:arial' id = "txt3"></textarea>
<textarea style='height:175px;font-family:arial' id = "txt4"></textarea>

решение jQuery настройте CSS в соответствии с вашими требованиями

css ...

div#container textarea {
    min-width: 270px;
    width: 270px;
    height: 22px;
    line-height: 24px;
    min-height: 22px;
    overflow-y: hidden; /* fixes scrollbar flash - kudos to @brettjonesdev */
    padding-top: 1.1em; /* fixes text jump on Enter keypress */
}

javascript ...

// auto adjust the height of
$('#container').delegate( 'textarea', 'keydown', function (){
    $(this).height( 0 );
    $(this).height( this.scrollHeight );
});
$('#container').find( 'textarea' ).keydown();

ИЛИ альтернатива для jQuery 1.7 + ...

// auto adjust the height of
$('#container').on( 'keyup', 'textarea', function (){
    $(this).height( 0 );
    $(this).height( this.scrollHeight );
});
$('#container').find( 'textarea' ).keyup();

Я создал скрипку с минимальным стилем в качестве отправной точки для ваших экспериментов ... http://jsfiddle.net/53eAy/951/

Это хорошо, но я бы добавил overflow-y: hidden; в CSS, чтобы полоса прокрутки не мигала на короткое время при изменении размера.

brettjonesdev 06.05.2013 19:11

Не совсем уверен, но без него текстовая область слишком сильно увеличивается. Я думаю, это связано с тем, как вычисляется scrollHeight элементов.

chim 21.06.2013 13:31

Мне очень нравится это решение, в первом примере как я могу ограничить количество строк и избавиться от отступов?

Darius 21.09.2013 11:12

Привет, Дариус, не уверен в том, чтобы избавиться от заполнения, пробовал все виды трюков с этим, но это либо заполнение, либо переход текста :(. Должно быть решение, поэтому я буду продолжать попытки. Верхний ответ хорошо работает с без отступов. Попробуйте одну из скрипок в комментарии @ChrisMoschini.

chim 23.09.2013 14:02

@Darius Я бы ограничил максимальное количество строк в javascript, добавив строку `if ($ (this) .height ()> maxHeight) {return; } где-то в самом верху. Вы можете установить для overflow-y значение auto, чтобы восстановить полосы прокрутки. Вам нужно будет запускать функцию при загрузке страницы, если вы условно добавляете полосы прокрутки.

chim 23.09.2013 14:18

Используйте несколько событий, чтобы работать для самых разных сценариев $('textarea.auto-resize').on('change cut paste drop keyup', function(){...})

raxith 04.05.2014 15:43

Прыгает как сумасшедший в Chrome 40 Win 8.1 на текстах длиннее области просмотра. Делает его совершенно непригодным для использования.

tobibeer 11.02.2015 16:59

Удерживание ввода (новая строка) приводит к прокрутке. Размер не меняется до тех пор, пока клавиша не будет отпущена.

Niels Abildgaard 23.04.2015 20:03

Я могу установить размер TextArea в IE9 и Chrome с помощью следующей функции jQuery. Он привязывается к объектам textarea из селектора, определенного в функции $ (document) .ready ().

function autoResize(obj, size) {
    obj.keyup(function () {
        if ($(this).val().length > size-1) {
            $(this).val( function() {
                $(this).height(function() {
                    return this.scrollHeight + 13;
                });
                alert('The maximum comment length is '+size+' characters.');
                return $(this).val().substring(0, size-1);
            });
        }
        $(this).height(function() {
            if  ($(this).val() == '') {
                return 15;
            } else {
                $(this).height(15);
                return ($(this).attr('scrollHeight')-2);
            }
        });
    }).keyup();
}

В моей функции $ (document) .ready () у меня есть следующий вызов для всех моих вызовов textarea на этой странице.

$('textarea').each( function() {
        autoResize($(this), 250);
});

Где 250 - это ограничение на количество символов в моей текстовой области. Он будет увеличиваться настолько, насколько позволяет размер текста (в зависимости от количества символов и размера шрифта). Он также будет соответствующим образом сжимать вашу текстовую область, когда вы удаляете символы из текстового поля или если пользователь изначально вставляет слишком много текста.

Я знаю короткий и правильный способ реализовать это с помощью jquery. Никаких дополнительных скрытых div не требуется и работает в большинстве браузеров.

<script type = "text/javascript">$(function(){
$("textarea").live("keyup keydown",function(){
var h=$(this);
h.height(60).height(h[0].scrollHeight);//where 60 is minimum height of textarea
});});

</script>

.live() jQuery устарел. api.jquery.com/live Обычно вы захотите использовать .on().

Luke 28.06.2014 02:22
<!DOCTYPE html>
<html>
<head>
    <meta charset = "UTF-8">
    <title>Textarea autoresize</title>
    <style>
    textarea {
        overflow: hidden;
    }
    </style>
    <script>
    function resizeTextarea(ev) {
        this.style.height = '24px';
        this.style.height = this.scrollHeight + 12 + 'px';
    }

    var te = document.querySelector('textarea');
    te.addEventListener('input', resizeTextarea);
    </script>
</head>
<body>
    <textarea></textarea>
</body>
</html>

Проверено в Firefox 14 и Chromium 18. Числа 24 и 12 произвольны, проверьте, что вам больше подходит.

Вы можете обойтись без тегов style и script, но это становится немного беспорядочным, imho (это старый стиль HTML + JS и не рекомендуется).

<textarea style = "overflow: hidden" onkeyup = "this.style.height='24px'; this.style.height = this.scrollHeight + 12 + 'px';"></textarea>

Обновлено: модернизированный код. Атрибут onkeyup изменен на addEventListener.
Обновлено: keydown работает лучше, чем keyup
Обновлено: объявить функцию перед использованием
Обновлено: ввод работает лучше, чем keydown (thnx @ WASD42 & @ MA-Maddin)

jsfiddle

У этого есть некоторые недостатки: 1) Textarea не будет изменять размер, тогда пользователь вставляет что-то только с помощью кнопок мыши; 2) Если пользователь вставит что-то с помощью клавиатуры (Ctrl + V), размер текстового поля будет изменен только тогда, когда он отпустит Ctrl. Если пользователь нажимает Ctrl + V несколько раз, то текстовое поле будет увеличиваться только после последнего. Вы должны добавить ту же функцию для вставки, вырезания, изменения и удаления событий.

WASD42 24.09.2013 18:10

Так что просто используйте вместо этого событие input. См. stackoverflow.com/a/14029861/1951524

Martin Schneider 22.11.2016 23:52

Улучшенная версия с поддержкой нескольких textarea в виде однострочника: document.querySelectorAll('textarea').forEach(function(te){ te.addEventListener("input", function() { this.style.height='24px'; this.style.height=this.scrollHeight+12+'px'; }); });

Meisner 29.01.2017 04:01

@Meisner Это короче, но я бы не сказал, что он "улучшился". С анонимной функцией невозможно вызвать removeEventListener и очистить ваши прослушиватели событий. Это особенно важно при создании прослушивателей событий повсюду в цикле forEach. К тому же, на мой взгляд, удобочитаемость гораздо важнее лаконичности.

GijsjanB 09.03.2017 12:52

для других и будущих меня убедитесь, что свойство box-sizing: border-box; установлено, иначе текстовое поле расширяется на 4 пикселя для каждого события onInput. Я потратил около 3 часов, пока не понял, что это проблема.

AIon 12.02.2019 22:53

Некоторые ответы здесь не учитывают заполнение.

Предполагая, что у вас есть maxHeight, о котором вы не хотите переходить, это сработало для меня:

    // obviously requires jQuery

    // element is the textarea DOM node

    var $el = $(element);
    // inner height is height + padding
    // outerHeight includes border (and possibly margins too?)
    var padding = $el.innerHeight() - $el.height();
    var originalHeight = $el.height();

    // XXX: Don't leave this hardcoded
    var maxHeight = 300;

    var adjust = function() {
        // reset it to the original height so that scrollHeight makes sense
        $el.height(originalHeight);

        // this is the desired height (adjusted to content size)
        var height = element.scrollHeight - padding;

        // If you don't want a maxHeight, you can ignore this
        height = Math.min(height, maxHeight);

        // Set the height to the new adjusted height
        $el.height(height);
    }

    // The input event only works on modern browsers
    element.addEventListener('input', adjust);

Вот что я сделал при использовании MVC HTML Helper для TextArea. У меня было довольно много элементов textarea, поэтому мне пришлось различать их с помощью Model Id.

 @Html.TextAreaFor(m => m.Text, 2, 1, new { id = "text" + Model.Id, onkeyup = "resizeTextBox(" + Model.Id + ");" })

и в скрипте добавил это:

   function resizeTextBox(ID) {            
        var text = document.getElementById('text' + ID);
        text.style.height = 'auto';
        text.style.height = text.scrollHeight + 'px';            
    }

Я тестировал его на IE10 и Firefox23

Есть несколько иной подход.

<div style = "position: relative">
  <pre style = "white-space: pre-wrap; word-wrap: break-word"></pre>
  <textarea style = "position: absolute; top: 0; left: 0; width: 100%; height: 100%"></textarea>
</div>

Идея состоит в том, чтобы скопировать текст из textarea в pre и позволить CSS убедиться, что они имеют одинаковый размер.

Преимущество состоит в том, что фреймворки предоставляют простые инструменты для перемещения текста, не касаясь каких-либо событий. А именно, в AngularJS вы должны добавить ng-model = "foo" ng-trim = "false" к textarea и ng-bind = "foo + '\n'" к pre. См. рабочий пример.

Просто убедитесь, что у pre такой же размер шрифта, как у textarea.

«Просто убедитесь, что у pre такой же размер шрифта, как у textarea.» - им нужен тот же line-height, а также такое же количество padding и / или border. Это лучшее решение для Angular.

Jamie Barker 20.01.2016 18:39

Лучшее простое решение, которое я видел и пытался придумать для реактивного обновления. Спасибо!

Alex Shink 23.11.2020 21:52

Если вам не нужна поддержка IE8, вы можете использовать событие input:

var resizingTextareas = [].slice.call(document.querySelectorAll('textarea[autoresize]'));

resizingTextareas.forEach(function(textarea) {
  textarea.addEventListener('input', autoresize, false);
});

function autoresize() {
  this.style.height = 'auto';
  this.style.height = this.scrollHeight+'px';
  this.scrollTop = this.scrollHeight;
  window.scrollTo(window.scrollLeft,(this.scrollTop+this.scrollHeight));
}

Теперь вам нужно только добавить немного CSS, и все готово:

textarea[autoresize] {
  display: block;
  overflow: hidden;
  resize: none;
}

Применение:

<textarea autoresize>Type here and I’ll resize.</textarea>

Вы можете узнать больше о том, как это работает в моем сообщении в блоге.

Хорошее решение, но требует небольшого исправления. Когда содержимое текстового поля загружено, например. из базы данных, текстовое поле остается маленьким. Вы должны вызвать событие input во время инициализации в цикле foreach.

Ajax 09.02.2016 17:27

Еще более простой и понятный подход:

// adjust height of textarea.auto-height
$(document).on( 'keyup', 'textarea.auto-height', function (e){
    $(this).css('height', 'auto' ); // you can have this here or declared in CSS instead
    $(this).height( this.scrollHeight );
}).keyup();

// и CSS

textarea.auto-height {
    resize: vertical;
    max-height: 600px; /* set as you need it */
    height: auto;      /* can be set here of in JS */
    overflow-y: auto;
    word-wrap:break-word
}

Все, что нужно, - это добавить класс .auto-height к любому textarea, на который вы хотите настроить таргетинг.

Протестировано в FF, Chrome и Safari. Сообщите мне, если это не сработает для вас по какой-либо причине. Но это самый чистый и простой способ работы. И отлично работает! : D

Вы пробовали удалить текст после редактирования? Текстовое поле рухнуло?

18C 18.11.2017 09:04

авто размер

https://github.com/jackmoore/autosize

Просто работает, автономно, популярно (3.0k + GitHub stars по состоянию на октябрь 2018), доступно на cdnjs) и легковесно (~ 3.5k). Демо:

<textarea id = "autosize" style = "width:200px;">a
J   b
c</textarea>
<script src = "https://cdnjs.cloudflare.com/ajax/libs/autosize.js/4.0.2/autosize.min.js"></script>
<script>autosize(document.querySelectorAll('#autosize'));</script>

Кстати, если вы используете редактор ACE, используйте maxLines: Infinity: Автоматически настраивать высоту содержимого в редакторе Ace Cloud 9

Версия 2 была выпущена в феврале 2015 года. Она стала проще и больше не зависит от jQuery.

crispy 01.03.2015 11:37

Извините, это работает. Может, я был в другом браузере .. так что, думаю, лучше проигнорировать мой комментарий ..

Toni Michel Caubet 02.06.2015 18:52

@ToniMichelCaubet ах, ладно, тогда может быть проблема с CDN. Дай мне проверить.

Ciro Santilli新疆棉花TRUMP BAN BAD 02.06.2015 18:54

Плагин autosize не позволяет вручную изменять размер с помощью значка изменения размера в текстовой области.

j4v1 03.05.2019 00:11

ПОЛНОЕ, ЕЩЕ ПРОСТОЕ РЕШЕНИЕ

Обновлен 2020-05-14(Улучшена поддержка браузером мобильных телефонов и планшетов)

Следующий код будет работать:

  • При вводе с клавиатуры.
  • Со вставленным текстом (щелкните правой кнопкой мыши & ctrl + v).
  • С вырезанным текстом (щелкните правой кнопкой мыши & ctrl + x).
  • С предварительно загруженным текстом.
  • Со всем сайтом textarea (многострочные текстовые поля).
  • С Fire Fox(проверено v31-67).
  • С Хром(проверено v37-74).
  • С IE(проверено v9-v11).
  • С Край(проверено v14-v18).
  • С IOS Safari.
  • С Браузер Android.
  • С помощью JavaScript строгий режим.
  • Проверено ли w3c.
  • И он оптимизирован и эффективен.

ВАРИАНТ 1 (С jQuery)

Эта опция требует jQuery, была протестирована и работает с 1.7.2 - 3.3.1

Простой(Добавьте этот код jquery в свой главный файл сценария и забудьте о нем.)

$("textarea").each(function () {
  this.setAttribute("style", "height:" + (this.scrollHeight) + "px;overflow-y:hidden;");
}).on("input", function () {
  this.style.height = "auto";
  this.style.height = (this.scrollHeight) + "px";
});
<script src = "https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<textarea placeholder = "Type, paste, cut text here...">PRELOADED TEXT.
This javascript should now add better support for IOS browsers and Android browsers.</textarea>
<textarea placeholder = "Type, paste, cut text here..."></textarea>

Test on jsfiddle


ВАРИАНТ 2 (Чистый JavaScript)

Простой(Добавьте этот JavaScript в свой главный файл сценария и забудьте о нем.)

const tx = document.getElementsByTagName("textarea");
for (let i = 0; i < tx.length; i++) {
  tx[i].setAttribute("style", "height:" + (tx[i].scrollHeight) + "px;overflow-y:hidden;");
  tx[i].addEventListener("input", OnInput, false);
}

function OnInput() {
  this.style.height = "auto";
  this.style.height = (this.scrollHeight) + "px";
}
<textarea placeholder = "Type, paste, cut text here...">PRELOADED TEXT. This JavaScript should now add better support for IOS browsers and Android browsers.</textarea>
<textarea placeholder = "Type, paste, cut text here..."></textarea>

Test on jsfiddle


ВАРИАНТ 3 (Расширение jQuery)

Полезно, если вы хотите применить дополнительную цепочку к текстовым областям, для которых требуется автоматический размер.

jQuery.fn.extend({
  autoHeight: function () {
    function autoHeight_(element) {
      return jQuery(element)
        .css({ "height": "auto", "overflow-y": "hidden" })
        .height(element.scrollHeight);
    }
    return this.each(function() {
      autoHeight_(this).on("input", function() {
        autoHeight_(this);
      });
    });
  }
});

Вызов с помощью $("textarea").autoHeight()


ОБНОВЛЕНИЕ ТЕКСТА С ПОМОЩЬЮ JAVASCRIPT

При внедрении содержимого в текстовое поле с помощью JavaScript добавьте следующий код для вызова функции в варианте 1.

$("textarea").trigger("input");

ПРЕДУСТАНОВЛЕННАЯ ВЫСОТА ТЕКСТА

Чтобы зафиксировать начальную высоту текстового поля, вам нужно будет добавить дополнительное условие:

const txHeight = 16;
const tx = document.getElementsByTagName("textarea");
for (let i = 0; i < tx.length; i++) {
  if (tx[i].value == '') {
    tx[i].setAttribute("style", "height:" + txHeight + "px;overflow-y:hidden;");
  } else {
    tx[i].setAttribute("style", "height:" + (tx[i].scrollHeight) + "px;overflow-y:hidden;");
  }
  tx[i].addEventListener("input", OnInput, false);
}

function OnInput(e) {
  this.style.height = "auto";
  this.style.height = (this.scrollHeight) + "px";
}
<textarea placeholder = "Type, paste, cut text here...">PRELOADED TEXT. This JavaScript should now add better support for IOS browsers and Android browsers.</textarea>
<textarea placeholder = "Type, paste, cut text here..."></textarea>

Это отличное решение, было бы немного более понятно, если бы имя метода и имя параметра были обновлены так, чтобы они были настоящими именами, а не отдельными буквами.

Chris Marisic 03.10.2014 19:34

@Obsidian я пробовал в IE10, он не работает .. если вы знаете какие-либо другие решения.

Elangovan 26.12.2015 15:38

@Elangovan Я не могу протестировать в IE10, но я ожидаю, что вариант 3 сработает. Ты это пробовал?

DreamTeK 04.01.2016 11:36

Довольно странно, что когда я использую $ ("# xxx"). Val ("xxx"). Trigger ("input"), он запускает событие ввода, однако атрибут .scrollHeight по-прежнему возвращает 0. Я не понимаю. . ржу не могу

WTIFS 30.08.2016 12:44

@WTIFS Не могу сказать, что заметил это раньше. Влияет ли это на то, чего вы пытаетесь достичь? Вы читаете значение после завершения триггерного события? Вы можете использовать функцию обратного вызова в конце функции.

DreamTeK 30.08.2016 13:47

@Obsidian Мне пришлось использовать Math.max (40, e.scrollHeight), чтобы избежать нулевой высоты. Что касается обратного звонка, не могли бы вы дать мне более подробную информацию? Я понятия не имею, как применить здесь обратный вызов.

WTIFS 30.08.2016 13:56

@WTIFS Я обновил скрипку, чтобы проверить прокрутку. Если этот флажок установлен во время обратного вызова ввода, высота прокрутки читается правильно. См. Предупреждение здесь при вводе. jsfiddle.net/n9uuv0hd/8

DreamTeK 30.08.2016 15:23

@Obsidian Спасибо! Я только что понял, почему я всегда получаю 0 - я помещаю текстовое поле в модальное окно Bootstrap! Поскольку модальное окно сначала скрыто, текстовое поле в нем будет иметь 0 scrollHeight ??

WTIFS 31.08.2016 07:03

@Obsidian Fantastic !! (Вариант 3). this.style.height = 'auto'; - это волшебное исправление поведения. Я был так расстроен, почему scrollHeight ведет себя так странно. Высота до auto, а затем сопоставление scrollHeight в том же цикле рендеринга все еще поражает меня, как он «исправляет» эту проблему, хотя технически он должен рисовать только вторую высоту.

bit-less 29.09.2016 19:49

Сегодня я попробовал вариант 3 в Chrome, и мне пришлось внести пару настроек. 1) Он не всегда будет правильно уменьшать размер, если у вас есть переход «высота» или «все» в текстовой области. Я бы не рекомендовал использовать переходы, влияющие на высоту. 2) scrollHeight возвращал минимум двух строк в высоту (возможно, потому, что это значение по умолчанию для текстовых полей в Chrome), но если вы измените this.style.height = 'auto'; в this.style.height = '0px'; и добавьте min-height, чтобы предотвратить фактическое изменение начального состояния до 0, scrollHeight будет правильно возвращать одну строку высоты, когда это необходимо.

ZorroDeLaArena 30.09.2016 17:08

@ZorroDeLaArena, спасибо, что отметили эти моменты. Вы правы, поведение по умолчанию для многострочного ввода - показывать несколько строк, даже если они пустые, если не указано иное.

DreamTeK 03.10.2016 10:42

@Obsidian Вы можете объяснить, как this.style.height = 'auto'; исправляет поведение scrollHeight? Это просто волшебство.

sidney 25.08.2017 09:05

@sidney Просто: сначала использование auto просто позволяет сбросить высоту текстового поля до высоты верный его содержимого до того, как изменения будут сделаны с помощью scrollheight.

DreamTeK 25.08.2017 11:14

Несколько вещей: я использую первый вариант в модальном окне. На мобильном телефоне он странным образом меняет прокрутку при наборе текста, что раздражает. Во-вторых: кнопки перехода на страницу вверх / вниз не работают с этим скриптом.

user5147563 03.09.2017 15:25

@Soaku Пожалуйста, не могли бы вы привести пример, поскольку у меня нет проблем ни с одним из упомянутых вами пунктов, но я хочу, чтобы сценарий был максимально эффективным, поэтому, если есть проблемы, я хотел бы их исправить.

DreamTeK 04.09.2017 11:08

@Obsidian Вы пробовали использовать текстовое поле с текстом, занимающим более 100% высоты экрана? Потом возникает первый глюк,

user5147563 04.09.2017 11:39

@Soaku да, jsfiddle.net/n9uuv0hd/94 отлично работает в chrome и работает как домашняя часть textarea в firefox. Можете ли вы придумать свою проблему?

DreamTeK 04.09.2017 12:12

@Obsidian На самом деле ошибка является присутствует в вашей скрипке. Когда я печатаю, прокрутка «телепортируется», поэтому указатель находится прямо в верхней части клавиатуры, когда я нажимаю «ввод», он возвращается в предыдущее положение.

user5147563 04.09.2017 12:24

@ZorroDeLaArena Спасибо за ваш вклад. Мне также нужно было отображать 1 строку, когда это необходимо, и this.style.height = '0px' устранил мою проблему.

Josh Bilderback 18.09.2017 22:45

@Obsidian К сожалению, похоже, из-за this.style.height = 'auto'; переходы CSS по высоте не работают. У меня могут работать переходы и изменение размера при удалении разорванных строк, либо переходы не работают, а изменение размера при удалении строк работает. Какие-нибудь обходные пути?

sidney 11.01.2018 07:27

@sidney Да, мне еще предстоит преодолеть эту трудность. Хотя я обнаружил, что изменение высоты, хотя выглядело хорошо, не было хорошо принято моей клиентской базой. В этом случае скорость важнее стиля!

DreamTeK 11.01.2018 14:30

elem [0] .scrollHeight может помочь в случае, если elem.scrollHeight не работает

bbe 29.01.2018 14:41

Работает ли он в динамически созданном текстовом поле после загрузки документа?

jjxtra 29.04.2019 23:17

@jjxtra Да, это так!

DreamTeK 30.04.2019 10:22

> Обновлено 05.07.2019 (улучшенная поддержка браузеров для мобильных телефонов и планшетов) Обновлено из будущего!

PW Kad 19.05.2019 19:23

@PWKad lol Нет, мы сначала используем НОРМАЛЬНЫЕ даты в Англии с наименьшим знаменателем. Дни, месяцы, годы. (Вы бы не стали читать часы Часы / Секунды / Минуты, не так ли?) Человек, которого вы знаете, не должен был делать такое предположение.

DreamTeK 20.05.2019 10:15

@DreamTeK большое спасибо, второй вариант работает как шарм!

sheriff_paul 06.08.2019 21:37

Почему мой не работает? В React тоже работает? Я включаю файл main.js в index.html, но он почему-то не работает. Похоже, функция не вызывается

Kittichote Kamalapirat 18.09.2019 13:13

@KittichoteKamalapirat, если вы создадите новый вопрос, показывающий пример вашего текущего кода, я был бы счастлив попытаться помочь вам с этим. На данный момент я бы удостоверился, что jQuery инициализирован до вашего файла main.js. Затем я бы проверил, что весь ваш файл main.js не содержит ошибок, потому что одна пропущенная точка с запятой приведет к сбою в вашем документе.

DreamTeK 19.09.2019 10:43

@DreamTeK Спасибо за ответ. Я добавил сюда вопрос, пожалуйста, проверьте его. Сообщите мне, если предоставленной мной информации недостаточно stackoverflow.com/questions/58008393/…

Kittichote Kamalapirat 19.09.2019 12:56

По какой-то причине мое текстовое поле остается на 0 пикселей при загрузке страницы даже с предварительно загруженным текстом. Я вижу, что он работает в примере jsfiddle (вариант 1), но у меня в приложении точно такой же код, и он не работает. :-( Это работает, когда я печатаю в текстовом поле, но не работает при загрузке страницы.

Vincent 02.01.2020 20:39

@Vincent Тогда у вас должен быть другой конфликтующий код в вашем приложении. Скорее всего, это css или Javascript. Попробуйте использовать веб-консоль браузера при запуске приложения, чтобы увидеть, какая высота применяется к текстовому полю.

DreamTeK 03.01.2020 12:07

По-прежнему существует вариант использования, на который не дан ответ в вашем примере: если начальная высота текстового поля не является автоматической? Пустой textarea имеет высоту в два ряда. Если я возьму jsfiddle из вашего второго примера и добавлю начальный style = "height: 33px" в пустое текстовое поле, вы увидите, что ваш код нарушает высоту текстового поля, снова делая его двумя строками ...

Fla 25.04.2020 01:19

@fla Код не ломается, он выполняет то, для чего был запрограммирован. Установка высоты встроенного стиля будет проигнорирована скриптом из-за специфики. Если вам нужна высота по умолчанию для пустого поля, вам нужно будет добавить предостережение в функцию javascript для проверки пустого содержимого, а затем установить начальную высоту по-другому. например, jsfiddle.net/fxre1zm5

DreamTeK 29.04.2020 13:56

Речь идет не о пустом содержимом, а о текстовом поле с одной строкой. Высота текстового поля должна быть высотой содержимого. Если мой контент находится только в одной строке, высота текстового поля должна быть одной строкой, а не двумя.

Fla 01.05.2020 14:44

@fla Вход с type = "textarea" по умолчанию является многострочным, однако вы можете изменить поведение по умолчанию, используя мое предложение. У вас это не сработало?

DreamTeK 04.05.2020 12:25

если у кого-то есть проблемы с начальной высотой текстового поля, просто получите и установите высоту ТОЛЬКО после установки overflow hidden $ el.style ['overflow-y'] = 'hidden'; $ el.style.height = $ el.scrollHeight + 'px';

dimson d 13.05.2020 19:04

Это должен быть принятый ответ. Вариант 2 работает как шарм.

Ulises Vargas De Sousa 09.01.2021 21:24

Я использовал "чистый javascript". Это действительно хорошо работает и определенно помогло мне. Спасибо! Как ни странно, мне не удалось заставить работать другую версию ответа, поэтому я очень рад, что вы добавили это.

RDragonrydr 21.02.2021 22:28

Кто-нибудь считал удовлетворенным? Не нужно возиться с прокруткой, и единственный JS, который мне нравится в нем, - это если вы планируете сохранять данные при размытии ... и, по-видимому, он совместим со всеми популярными браузерами: http://caniuse.com/#feat=contenteditable

Просто стилизуйте его так, чтобы он выглядел как текстовое поле, и он автоматически изменит размер ... Сделайте его минимальную высоту предпочтительной высотой текста и установите ее.

Что круто в этом подходе, так это то, что вы можете сохранять теги и в некоторых браузерах.

http://jsfiddle.net/gbutiri/v31o8xfo/

var _auto_value = '';
$(document).on('blur', '.autosave', function(e) {
  var $this = $(this);
  if ($this.text().trim() == '') {
    $this.html('');
  }

  // The text is here. Do whatever you want with it.
  $this.addClass('saving');

  if (_auto_value !== $this.html() || $this.hasClass('error')) {

    // below code is for example only.
    $.ajax({
      url: '/echo/json/?action=xyz_abc',
      data: 'data=' + $this.html(),
      type: 'post',
      datatype: 'json',
      success: function(d) {
        console.info(d);
        $this.removeClass('saving error').addClass('saved');
        var k = setTimeout(function() {
          $this.removeClass('saved error')
        }, 500);
      },
      error: function() {
        $this.removeClass('saving').addClass('error');
      }
    });
  } else {
    $this.removeClass('saving');
  }
}).on('focus mouseup', '.autosave', function() {
  var $this = $(this);
  if ($this.text().trim() == '') {
    $this.html('');
  }
  _auto_value = $this.html();
}).on('keyup', '.autosave', function(e) {
  var $this = $(this);
  if ($this.text().trim() == '') {
    $this.html('');
  }
});
body {
  background: #3A3E3F;
  font-family: Arial;
}

label {
  font-size: 11px;
  color: #ddd;
}

.autoheight {
  min-height: 16px;
  font-size: 16px;
  margin: 0;
  padding: 10px;
  font-family: Arial;
  line-height: 20px;
  box-sizing: border-box;
  -o-box-sizing: border-box;
  -moz-box-sizing: border-box;
  -webkit-box-sizing: border-box;
  overflow: hidden;
  display: block;
  resize: none;
  border: 0;
  outline: none;
  min-width: 200px;
  background: #ddd;
  max-height: 400px;
  overflow: auto;
}

.autoheight:hover {
  background: #eee;
}

.autoheight:focus {
  background: #fff;
}

.autosave {
  -webkit-transition: all .2s;
  -moz-transition: all .2s;
  transition: all .2s;
  position: relative;
  float: none;
}

.autoheight * {
  margin: 0;
  padding: 0;
}

.autosave.saving {
  background: #ff9;
}

.autosave.saved {
  background: #9f9;
}

.autosave.error {
  background: #f99;
}

.autosave:hover {
  background: #eee;
}

.autosave:focus {
  background: #fff;
}

[contenteditable=true]:empty:before {
  content: attr(placeholder);
  color: #999;
  position: relative;
  top: 0px;
  /*
    For IE only, do this:
    position: absolute;
    top: 10px;
    */
  cursor: text;
}
<script src = "https://cdnjs.cloudflare.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<label>Your Name</label>
<div class = "autoheight autosave contenteditable" contenteditable = "true" placeholder = "Your Name"></div>

Chrome добавит элементы <div> при вводе.

sbaechler 04.11.2016 21:36
contenteditable хорош, но если вам нужен открытый текст, ему понадобится множество опций, таких как -webkit-user-modify: read-write-plaintext-only и white-space: pre-wrap.
mik01aj 12.12.2017 14:02

@_sbaechler: <div> опускаются при использовании [dom-element].innerText. @WebmasterG IMHO было бы неплохо опустить jquery (для прозрачности) и включить пример на этой странице через исполняемый фрагмент кода вместо jsfiddle.

adabru 06.08.2018 11:46

Я не знаю, упоминал ли кто-нибудь об этом, но в некоторых случаях можно изменить высоту с помощью атрибутов строк

textarea.setAttribute('rows',breaks);

Демо

Это работает, только если у вас есть white-space: nowrap;. Когда строка переносится на другую строку без разрыва строки, текстовое поле больше не будет правильно настроено.

Yeti 10.08.2017 14:08

Вы можете использовать этот код:

Гроб:

jQuery.fn.extend autoHeightTextarea: ->
  autoHeightTextarea_ = (element) ->
    jQuery(element).css(
      'height': 'auto'
      'overflow-y': 'hidden').height element.scrollHeight

  @each ->
    autoHeightTextarea_(@).on 'input', ->
      autoHeightTextarea_ @

$('textarea_class_or_id`').autoHeightTextarea()

Javascript

jQuery.fn.extend({
  autoHeightTextarea: function() {
    var autoHeightTextarea_;
    autoHeightTextarea_ = function(element) {
      return jQuery(element).css({
        'height': 'auto',
        'overflow-y': 'hidden'
      }).height(element.scrollHeight);
    };
    return this.each(function() {
      return autoHeightTextarea_(this).on('input', function() {
        return autoHeightTextarea_(this);
      });
    });
  }
});

$('textarea_class_or_id`').autoHeightTextarea();

Для тех, кто хочет, чтобы размер текстового поля автоматически изменялся как по ширине, так и по высоте:

HTML:

<textarea class='textbox'></textarea>
<div>
  <span class='tmp_textbox'></span>
</div>

CSS:

.textbox,
.tmp_textbox {
  font-family: 'Arial';
  font-size: 12px;
  resize: none;
  overflow:hidden;
}

.tmp_textbox {
  display: none;
}

jQuery:

$(function(){
  //alert($('.textbox').css('padding'))
  $('.textbox').on('keyup change', checkSize)
  $('.textbox').trigger('keyup')

  function checkSize(){
    var str = $(this).val().replace(/\r?\n/g, '<br/>');
    $('.tmp_textbox').html( str )
    console.info($(this).val())

    var strArr = str.split('<br/>')
    var row = strArr.length
    $('.textbox').attr('rows', row)
    $('.textbox').width( $('.tmp_textbox').width() + parseInt($('.textbox').css('padding')) * 2 + 10 )
  }
})

Codepen:

http://codepen.io/anon/pen/yNpvJJ

Ваше здоровье,

Лучшее решение (работает и коротко) для меня:

    $(document).on('input', 'textarea', function () {
        $(this).outerHeight(38).outerHeight(this.scrollHeight); // 38 or '1em' -min-height
    }); 

Он работает как шарм, не мигая при вставке (также с помощью мыши), вырезании, вводе и уменьшении до нужного размера.

Пожалуйста, взгляните на jsFiddle.

Потрясающий!!! однострочное дело! глупый вопрос, как я могу добавить анимацию при изменении размера? например, текстовое поле мягко меняет размер, а не прыгает к размеру?

user2513846 22.03.2016 09:07

@ user2513846 Похоже, это невозможно из-за дизайна многострочного редактирования. Я сделал пример анимации размера текстового поля: jsfiddle.net/yk2g333e Как вы знаете, текстовый курсор опускается вниз в точке и строки или курсора, поэтому, если в этот момент нет паузы, анимировать нечего. Но пауза будет раздражать пользователя.

vatavale 23.03.2016 14:32

@ user2513846 Однако с еще одной пустой строкой в ​​конце textarea можно получить плавную анимацию: jsfiddle.net/p23erdfr

vatavale 23.03.2016 15:15

Полезная настройка для этого решения - также скрыть вертикальную полосу прокрутки (видно в jsFiddle, здесь не упоминается), вы делаете это с помощью встроенного стиля (style = "overflow: hidden") или правильного с помощью: textarea {overflow: hidden;}

Gregor Simončič 03.10.2020 20:21

@Gregor Simončič Да, особенно для длинного текста - он дает правильный расчет целевой высоты текстового поля. Кроме того, для точного расчета лучше установить outerHeight равным 0.

vatavale 04.10.2020 17:22

Решение jQuery состоит в том, чтобы установить высоту текстового поля на 'auto', проверить scrollHeight и затем адаптировать высоту текстового поля к этому каждый раз, когда текстовое поле изменяется (JSFiddle):

$('textarea').on( 'input', function(){
    $(this).height( 'auto' ).height( this.scrollHeight );
});

Если вы динамически добавляете текстовые поля (через AJAX или что-то еще), вы можете добавить это в свой $ (document) .ready, чтобы убедиться, что все текстовые поля с классом autoheight сохраняются на той же высоте, что и их содержимое:

$(document).on( 'input', 'textarea.autoheight', function() {
    $(this).height( 'auto' ).height( this.scrollHeight );
});

Протестировано и работает в Chrome, Firefox, Opera и IE. Также поддерживает вырезание и вставку, длинные слова и т. д.

Если вы загружаете текстовую область с исходным содержимым через AJAX, вы можете захотеть запустить «ввод», чтобы убедиться, что высота правильная при инициализации, поэтому после загрузки текстовой области вызовите $ ('textarea') .trigger (' Вход' );

patrick 02.07.2016 18:39

Этот код работает для вставки, а также для удаления.

onKeyPressTextMessage = function(){
			var textArea = event.currentTarget;
    	textArea.style.height = 'auto';
    	textArea.style.height = textArea.scrollHeight + 'px';
};
<textarea onkeyup = "onKeyPressTextMessage(event)" name = "welcomeContentTmpl" id = "welcomeContent" onblur = "onblurWelcomeTitle(event)" rows = "2" cols = "40" maxlength = "320"></textarea>

Вот JSFiddle

Просто используйте <pre> </pre> с некоторыми стилями, например:

    pre {
        font-family: Arial, Helvetica, sans-serif;
        white-space: pre-wrap;
        word-wrap: break-word;
        font-size: 12px;
        line-height: 16px;
    }

это не полное решение.

18C 18.11.2017 09:06

Я рекомендую библиотеку javascript от http://javierjulio.github.io/textarea-autosize.

В комментариях добавьте пример кодового блока при использовании плагина:

<textarea class = "js-auto-size" rows = "1"></textarea>

<script src = "http://code.jquery.com/jquery-2.1.0.min.js"></script>
<script src = "jquery.textarea_autosize.min.js"></script>
<script>
$('textarea.js-auto-size').textareaAutoSize();
</script>

Минимальный необходимый CSS:

textarea {
  box-sizing: border-box;
  max-height: 160px; // optional but recommended
  min-height: 38px;
  overflow-x: hidden; // for Firefox (issue #5)
}

Вы можете использовать этот фрагмент кода для вычисления количества строк, необходимых для текстового поля:

textarea.rows = 1;
    if (textarea.scrollHeight > textarea.clientHeight)
      textarea.rows = textarea.scrollHeight / textarea.clientHeight;

Вычислите его на событиях input и window:resize, чтобы получить эффект автоматического изменения размера. Пример в Angular:

Код шаблона:

<textarea rows = "1" reAutoWrap></textarea>

auto-wrap.directive.ts

import { Directive, ElementRef, HostListener } from '@angular/core';

@Directive({
  selector: 'textarea[reAutoWrap]',
})
export class AutoWrapDirective {

  private readonly textarea: HTMLTextAreaElement;

  constructor(el: ElementRef) {
    this.textarea = el.nativeElement;
  }

  @HostListener('input') onInput() {
    this.resize();
  }

  @HostListener('window:resize') onChange() {
    this.resize();
  }

  private resize() {
    this.textarea.rows = 1;
    if (this.textarea.scrollHeight > this.textarea.clientHeight)
      this.textarea.rows = this.textarea.scrollHeight / this.textarea.clientHeight;
  }

}

Следующие действия предназначены для вырезания, вставки и т. д., Независимо от того, выполняются ли эти действия с помощью мыши, сочетания клавиш, выбора параметра в строке меню ... в нескольких ответах используется аналогичный подход, но они не учитывают поле - размер, из-за чего неправильно применяют стиль overflow: hidden.

Я делаю следующее, что также хорошо работает с max-height и rows для минимальной и максимальной высоты.

function adjust() {
  var style = this.currentStyle || window.getComputedStyle(this);
  var boxSizing = style.boxSizing === 'border-box'
      ? parseInt(style.borderBottomWidth, 10) +
        parseInt(style.borderTopWidth, 10)
      : 0;
  this.style.height = '';
  this.style.height = (this.scrollHeight + boxSizing) + 'px';
};

var textarea = document.getElementById("ta");
if ('onpropertychange' in textarea) { // IE
  textarea.onpropertychange = adjust;
} else if ('oninput' in textarea) {
  textarea.oninput = adjust;
}
setTimeout(adjust.bind(textarea));
textarea {
  resize: none;
  max-height: 150px;
  border: 1px solid #999;
  outline: none;
  font: 18px sans-serif;
  color: #333;
  width: 100%;
  padding: 8px 14px;
  box-sizing: border-box;
}
<textarea rows = "3" id = "ta">
Try adding several lines to this.
</textarea>

Для абсолютной полноты вам следует вызвать функцию adjust еще в нескольких случаях:

  1. События изменения размера окна, если ширина textarea изменяется с изменением размера окна, или другие события, которые изменяют ширину текстовой области
  2. Когда атрибут стиля textareadisplay изменяется, например когда он переходит с none (скрыт) на block
  3. При программном изменении значения textarea

Обратите внимание, что использование window.getComputedStyle или получение currentStyle может быть довольно затратным с вычислительной точки зрения, поэтому вместо этого вы можете захотеть кэшировать результат.

Работает для IE6, так что я очень надеюсь, что это достаточно хорошая поддержка.

Вот директива angularjs для ответа panzi.

 module.directive('autoHeight', function() {
        return {
            restrict: 'A',
            link: function(scope, element, attrs) {
                element = element[0];
                var resize = function(){
                    element.style.height = 'auto';
                    element.style.height = (element.scrollHeight)+'px';
                };
                element.addEventListener('change', resize, false);
                element.addEventListener('cut',    resize, false);
                element.addEventListener('paste',  resize, false);
                element.addEventListener('drop',   resize, false);
                element.addEventListener('keydown',resize, false);

                setTimeout(resize, 100);
            }
        };
    });

HTML:

<textarea ng-model = "foo" auto-height></textarea>

Вам лучше использовать $ timeout, чем setTimout - это обеспечит инициализацию модели (не нужно указывать миллисекунды - она ​​будет выполнена после цикла дайджеста Angular). Также element = element [0]; это очень плохая практика ... В любом случае решение не подходит для меня, так как мне нужно, чтобы текстовое поле было однострочным, пока не будет больше текста.

Karol Websky 12.12.2017 16:23

Нативное решение Javascript без мерцания в Firefox и быстрее, чем метод withclientHeight ...

1) Добавьте селектор div.textarea ко всем вашим селекторам, содержащим textarea. Не забываем добавить box-sizing: border-box;

2) Включите этот скрипт:

function resizeAll()
{
   var textarea=document.querySelectorAll('textarea');
   for(var i=textarea.length-1; i>=0; i--)
      resize(textarea[i]);
}

function resize(textarea)
{
   var div = document.createElement("div");
   div.setAttribute("class","textarea");
   div.innerText=textarea.value+"\r\n";
   div.setAttribute("style","width:"+textarea.offsetWidth+'px;display:block;height:auto;left:0px;top:0px;position:fixed;z-index:-200;visibility:hidden;word-wrap:break-word;overflow:hidden;');
   textarea.form.appendChild(div);
   var h=div.offsetHeight;
   div.parentNode.removeChild(div);
   textarea.style.height=h+'px';
}

function resizeOnInput(e)
{
   var textarea=document.querySelectorAll('textarea');
   for(var i=textarea.length-1; i>=0; i--)
      textarea[i].addEventListener("input",function(e){resize(e.target); return false;},false);
}

window.addEventListener("resize",function(){resizeAll();}, false);
window.addEventListener("load",function(){resizeAll();}, false);
resizeOnInput();

Протестировано в IE11, Firefox и Chrome.

Это решение создает div, похожий на ваше текстовое поле, включая внутренний текст и измеряет высоту.

В качестве другого подхода вы можете использовать <span>, который автоматически регулирует свой размер. Вам нужно будет сделать его редактируемым, добавив свойство contenteditable = "true", и все готово:

div {
  width: 200px;
}

span {
  border: 1px solid #000;
  padding: 5px;
}
<div>
  <span contenteditable = "true">This text can be edited by the user</span>
</div>

Единственная проблема с этим подходом заключается в том, что если вы хотите отправить значение как часть формы, вам придется сделать это самостоятельно в JavaScript. Сделать это относительно просто. Например, вы можете добавить скрытое поле и в событии onsubmit формы присвоить значение span скрытому полю, которое затем будет автоматически отправлено вместе с формой.

На этой странице уже есть ответ с использованием contenteditable: stackoverflow.com/questions/454202/…

adabru 06.08.2018 11:42

@adabru Да, но это не одно и то же. Тойота делает красные машины, и Форд тоже делает красные машины, но ведь они разные, не так ли? Если вам больше нравится другой ответ, продолжайте. Но есть те, кто больше ценит мой ответ и согласен с ним. Иметь разные варианты - хорошо.

Racil Hilan 10.08.2018 09:59

Кажется, ни один из ответов не работает. Но это работает для меня: https://coderwall.com/p/imkqoq/resize-textarea-to-fit-content

$('#content').on( 'change keyup keydown paste cut', 'textarea', function (){
    $(this).height(0).height(this.scrollHeight);
}).find( 'textarea' ).change();

Это должен быть принятый ответ, хотя его достаточно, чтобы прослушивать события "keyup".

Bob Ross 11.12.2019 15:08

Сделайте TextArea изменяемым размером, который использует q Query

function MakeTextAreaResisable(id) {
    var o = $(id);
    o.css("overflow-y", "hidden");

    function ResizeTextArea() {
        o.height('auto');
        o.height(o[0].scrollHeight);
    }

    o.on('change', function (e) {
        ResizeTextArea();
    });

    o.on('cut paste drop keydown', function (e) {
        window.setTimeout(ResizeTextArea, 0);
    });

    o.focus();
    o.select();
    ResizeTextArea();
}

Вы можете использовать JQuery для расширения textarea при вводе:

$(document).find('textarea').each(function () {
  var offset = this.offsetHeight - this.clientHeight;

  $(this).on('keyup input focus', function () {
    $(this).css('height', 'auto').css('height', this.scrollHeight + offset);
  });
});
<script src = "https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>

<div>
<textarea name = "note"></textarea>
<div>

Самое чистое решение. но мы должны прекратить использование jQuery: textarea.addEventListener ('keyup', () => {textarea.style.height = 0; textarea.style.height = ${textarea.scrollHeight}px;});

Toni Michel Caubet 06.02.2019 13:30

Лучший способ, который я нашел:

$("textarea.auto-grow").each( function(){
    $(this).keyup(function(){
        $(this).height( $(this)[0].scrollHeight - Number( $(this).css("font-size").replace("px", "") ) );
    });
});

У других способов есть ошибка размера шрифта.

Вот почему это лучшее.

Тем, кто хочет добиться того же в новых версиях Angular.

Возьмите textArea elementRef.

@ViewChild('textArea', { read: ElementRef }) textArea: ElementRef;

public autoShrinkGrow() {
    textArea.style.overflow = 'hidden';
    textArea.style.height = '0px';
    textArea.style.height = textArea.scrollHeight + 'px';
}

<textarea (keyup) = "autoGrow()" #textArea></textarea>

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

  public autoGrowShrinkToCertainHeight() {
    const textArea = this.textArea.nativeElement;
    if (textArea.scrollHeight > 77) {
      textArea.style.overflow = 'auto';
      return;
    }
    else {
      textArea.style.overflow = 'hidden';
      textArea.style.height = '0px';
      textArea.style.height = textArea.scrollHeight + 'px';
    }
  }

моя реализация очень проста, подсчитайте количество строк во вводе (и минимум 2 строки, чтобы показать, что это текстовое поле):

textarea.rows = Math.max(2, textarea.value.split("\n").length) // # oninput

полный рабочий пример со стимулом: https://jsbin.com/kajosolini/1/edit?html,js,output

(и это работает, например, с ручкой изменения размера браузера)

Это работает только в том случае, если вы разорвите строку, нажав «Enter». Если ваш текст длиннее, чем ширина текстового поля, но вы не нажимаете «ввод», он не расширяется.

Nathalia Xavier 24.07.2019 12:05

Я создал небольшой (7 КБ) настраиваемый элемент, который занимается всей этой логикой изменения размера за вас.

Он работает везде, потому что реализован как настраиваемый элемент. В том числе: виртуальные модели DOM (React, Elm и т. д.), Рендеринг на стороне сервера, например PHP, и простые скучные файлы HTML.

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

Вот как это работает:

// At the top of one of your Javascript files
import "autoheight-textarea";

или включить как тег скрипта

<script src = "//cdn.jsdelivr.net/npm/[email protected]/dist/main.min.js"></script>

затем просто оберните элементы textarea так

HTML файл

<autoheight-textarea>
  <textarea rows = "4" placeholder = "Type something"></textarea>
<autoheight-textarea>

Компонент React.js

const MyComponent = () => {
  return (
    <autoheight-textarea>
      <textarea rows = {4} placeholder = "Type something..." />
    </autoheight-textarea>
  );
}

Вот базовая демонстрация на Codesandbox: https://codesandbox.io/s/unruffled-http-2vm4c

И вы можете скачать пакет здесь: https://www.npmjs.com/package/autoheight-textarea

Если вам просто интересно увидеть логику изменения размера, вы можете взглянуть на эту функцию: https://github.com/Ahrengot/autoheight-textarea/blob/master/src/index.ts#L74-L85

Нашел один лайнер от здесь;

<textarea name = "text" oninput = "this.style.height = ''; this.style.height = this.scrollHeight +'px'"></textarea>

Принятый ответ работает нормально. Но это очень много кода для этой простой функции. Приведенный ниже код поможет.

   $(document).on("keypress", "textarea", function (e) {
    var height = $(this).css("height");
    var iScrollHeight = $(this).prop("scrollHeight");
    $(this).css('height',iScrollHeight);
    });

Это jQuery-версия отвечатьМуссави7.

$(function() {
  $("textarea.auto-grow").on("input", function() {
    var element = $(this)[0];
    element.style.height = "5px";
    element.style.height = (element.scrollHeight) + "px";
  });
})
textarea {
  resize: none;
  overflow: auto;
  width: 100%;
  min-height: 50px;
  max-height: 150px;
}
<script src = "https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<textarea class = "auto-grow"></textarea>

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

<textarea id = "my-text-area"></textarea>

<script>
  $(function() {
    const txtArea = $('#my-text-area')
    const val = txtArea.val()
    const rowLength = val.split('\n')
    txtArea.attr('rows', rowLength)
  })
</script>

для Angular 2+ просто сделайте это

<textarea (keydown) = "resize($event)"></textarea>


resize(e) {
    setTimeout(() => {
      e.target.style.height = 'auto';
      e.target.style.height = (e.target.scrollHeight)+'px';
    }, 0);
  }

textarea {
  resize: none;
  overflow: hidden;
}

Другие вопросы по теме