Был еще одна ветка об этом, который я пробовал. Но есть одна проблема: 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 )
};
}
Моя функция делает ошибку. Обязательно вводить новую строку в конце строки. Это лучшее решение. james.padolsey.com/javascript/jquery-plugin-autoresize
возможный дубликат Автоматическое изменение размера текстового поля с использованием прототипа
Вы можете попробовать мой плагин для этого: github.com/AndrewDryga/jQuery.Textarea.Autoresize
Я создал для этого пакет, если вы используете реакцию: npmjs.com/package/react-fluid-textarea
Сортировка и сладкий ответ здесь: 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>



![Безумие обратных вызовов в javascript [JS]](https://i.imgur.com/WsjO6zJb.png)


Вы используете более высокое значение текущего 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 ...
Единственное, что у меня есть, - это Konqueror, который возвращает clientHeight как scrollHeight. Это поведение, которого вы можете ожидать, если браузер не применяет блочную модель CSS к внутренним компонентам виджетов, что они не всегда делали, и стандарт не говорит, что они должны.
Я тестировал скрипт в обычных браузерах, и он не удался в 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. Вы не рассматривали перенос текста.
@EasternMonk, если вы попробуете, он действительно работает хорошо и довольно интуитивно понятен ИМХО: jsbin.com/tilokafasa/1/edit?html,js,output
$('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, текстовое поле не сжимается. Но близко!
@ChrisMoschini Я немного изменил код. Это работает для вас?
Используя тестер IE, приведенный выше код работает даже с IE 5.5. Я не тестировал IE 9, потому что в моем VirtualBox установлена только XP.
Оно делает! Сделал для вас jsfiddle: jsfiddle.net/CbqFv Теперь он работает в Chrome, Firefox и IE8 - хотя в IE8 он немного глючит. Когда вы увеличиваете или уменьшаете количество строк, это немного пугает. Как вы могли видеть в плагине автоизменения размера для jQuery, они работают над этим, клонируя текстовое поле, устанавливая его высоту на auto вместо оригинала, а затем используя это, чтобы установить высоту прокрутки на оригинале. Я сделал это в этой обновленной скрипке: jsfiddle.net/CbqFv/2 Это решает проблему IE, но Firefox перестает работать.
Привет, Панзи, все отлично работает. Но есть ли способ заставить эту работу работать с несколькими текстовыми полями на одной странице?
@HelenNeely: Да, просто примените его ко всем текстовым полям.
Спасибо, но я вижу, что он использует id = 'text' для поиска DOM. Но я не могу использовать один и тот же идентификатор для нескольких текстовых полей, так как мне изменить его на класс, который могут использовать другие? Еще раз спасибо.
@HelenNeely: Тогда не используйте идентификатор. Например. использовать класс и делать то, что init делает для всех элементов этого класса. Это должно быть задание для новичков.
Если вы хотите настроить таргетинг на современные браузеры, вам не нужно прикреплять обработчик ко всем этим событиям. Просто прикрепите к событию input или oninput.
@ DenilsonSá Если бы можно было предположить, что используются только современные браузеры, Интернет был бы лучшим местом.
Работает ли это, если у меня есть несколько текстовых полей, для которых требуется эта функция?
Это не сработает, если в IE11 есть полоса прокрутки. Если вы используете эту скрипку jsfiddle.net/CbqFv и вводите строки, пока у вас не появится полоса прокрутки, вы ее увидите. Любые идеи?
kaljak, помогает ли добавление overflow: hidden;? Обновлено: подождите, это уже есть. Тогда понятия не имею.
Что я могу сделать, чтобы полоса прокрутки не мигала? Если стиль overflow:auto;
@ollazarev Может быть, использовать visibility:hidden;position:fixed; textarea / div для измерения высоты? Или используйте contentEditable = "true"-div вместо текстового поля (что сильно усложняет другие вещи).
Это полностью нарушается, если текстовое поле находится рядом с нижним концом страницы - все прыгает назад и вперед из-за style.height='auto'. Я подозреваю, что решение состоит в том, чтобы добавить скрытого родственника, используемого только для измерения.
будет ли он зависать в браузере, если вставить большой текст внутрь, например, файл размером 3 МБ, после загрузки и получения ответа обратно в текстовое поле
В Firefox 70 размер первого переполненного символа не изменяется. На втором символе он изменяется.
Это отлично работает с JSFuddle, но мне интересно (поскольку у меня есть такая задача), как он себя ведет, если вы увеличиваете и уменьшаете размер шрифта в настройках браузера. Также на разных языках?
rows = 1 решил мою проблему
Немного исправлений. Отлично работает в 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;
});
работает до тех пор, пока ваши строки не переполняются - тогда они не поместятся.
Я использовал следующий код для нескольких текстовых полей. Работает нормально в 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 = attachAutoResizeEventstextarea {
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, чтобы полоса прокрутки не мигала на короткое время при изменении размера.
Не совсем уверен, но без него текстовая область слишком сильно увеличивается. Я думаю, это связано с тем, как вычисляется scrollHeight элементов.
Мне очень нравится это решение, в первом примере как я могу ограничить количество строк и избавиться от отступов?
Привет, Дариус, не уверен в том, чтобы избавиться от заполнения, пробовал все виды трюков с этим, но это либо заполнение, либо переход текста :(. Должно быть решение, поэтому я буду продолжать попытки. Верхний ответ хорошо работает с без отступов. Попробуйте одну из скрипок в комментарии @ChrisMoschini.
@Darius Я бы ограничил максимальное количество строк в javascript, добавив строку `if ($ (this) .height ()> maxHeight) {return; } где-то в самом верху. Вы можете установить для overflow-y значение auto, чтобы восстановить полосы прокрутки. Вам нужно будет запускать функцию при загрузке страницы, если вы условно добавляете полосы прокрутки.
Используйте несколько событий, чтобы работать для самых разных сценариев $('textarea.auto-resize').on('change cut paste drop keyup', function(){...})
Прыгает как сумасшедший в Chrome 40 Win 8.1 на текстах длиннее области просмотра. Делает его совершенно непригодным для использования.
Удерживание ввода (новая строка) приводит к прокрутке. Размер не меняется до тех пор, пока клавиша не будет отпущена.
Я могу установить размер 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().
<!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)
У этого есть некоторые недостатки: 1) Textarea не будет изменять размер, тогда пользователь вставляет что-то только с помощью кнопок мыши; 2) Если пользователь вставит что-то с помощью клавиатуры (Ctrl + V), размер текстового поля будет изменен только тогда, когда он отпустит Ctrl. Если пользователь нажимает Ctrl + V несколько раз, то текстовое поле будет увеличиваться только после последнего. Вы должны добавить ту же функцию для вставки, вырезания, изменения и удаления событий.
Так что просто используйте вместо этого событие input. См. stackoverflow.com/a/14029861/1951524
Улучшенная версия с поддержкой нескольких textarea в виде однострочника: document.querySelectorAll('textarea').forEach(function(te){ te.addEventListener("input", function() { this.style.height='24px'; this.style.height=this.scrollHeight+12+'px'; }); });
@Meisner Это короче, но я бы не сказал, что он "улучшился". С анонимной функцией невозможно вызвать removeEventListener и очистить ваши прослушиватели событий. Это особенно важно при создании прослушивателей событий повсюду в цикле forEach. К тому же, на мой взгляд, удобочитаемость гораздо важнее лаконичности.
для других и будущих меня убедитесь, что свойство box-sizing: border-box; установлено, иначе текстовое поле расширяется на 4 пикселя для каждого события onInput. Я потратил около 3 часов, пока не понял, что это проблема.
Некоторые ответы здесь не учитывают заполнение.
Предполагая, что у вас есть 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.
Лучшее простое решение, которое я видел и пытался придумать для реактивного обновления. Спасибо!
Если вам не нужна поддержка 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.
Еще более простой и понятный подход:
// 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
Вы пробовали удалить текст после редактирования? Текстовое поле рухнуло?
авто размер
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.
Извините, это работает. Может, я был в другом браузере .. так что, думаю, лучше проигнорировать мой комментарий ..
@ToniMichelCaubet ах, ладно, тогда может быть проблема с CDN. Дай мне проверить.
Плагин autosize не позволяет вручную изменять размер с помощью значка изменения размера в текстовой области.
Обновлен 2020-05-14(Улучшена поддержка браузером мобильных телефонов и планшетов)
Следующий код будет работать:
Эта опция требует 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>Простой(Добавьте этот 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>Полезно, если вы хотите применить дополнительную цепочку к текстовым областям, для которых требуется автоматический размер.
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 добавьте следующий код для вызова функции в варианте 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>Это отличное решение, было бы немного более понятно, если бы имя метода и имя параметра были обновлены так, чтобы они были настоящими именами, а не отдельными буквами.
@Obsidian я пробовал в IE10, он не работает .. если вы знаете какие-либо другие решения.
@Elangovan Я не могу протестировать в IE10, но я ожидаю, что вариант 3 сработает. Ты это пробовал?
Довольно странно, что когда я использую $ ("# xxx"). Val ("xxx"). Trigger ("input"), он запускает событие ввода, однако атрибут .scrollHeight по-прежнему возвращает 0. Я не понимаю. . ржу не могу
@WTIFS Не могу сказать, что заметил это раньше. Влияет ли это на то, чего вы пытаетесь достичь? Вы читаете значение после завершения триггерного события? Вы можете использовать функцию обратного вызова в конце функции.
@Obsidian Мне пришлось использовать Math.max (40, e.scrollHeight), чтобы избежать нулевой высоты. Что касается обратного звонка, не могли бы вы дать мне более подробную информацию? Я понятия не имею, как применить здесь обратный вызов.
@WTIFS Я обновил скрипку, чтобы проверить прокрутку. Если этот флажок установлен во время обратного вызова ввода, высота прокрутки читается правильно. См. Предупреждение здесь при вводе. jsfiddle.net/n9uuv0hd/8
@Obsidian Спасибо! Я только что понял, почему я всегда получаю 0 - я помещаю текстовое поле в модальное окно Bootstrap! Поскольку модальное окно сначала скрыто, текстовое поле в нем будет иметь 0 scrollHeight ??
@Obsidian Fantastic !! (Вариант 3). this.style.height = 'auto'; - это волшебное исправление поведения. Я был так расстроен, почему scrollHeight ведет себя так странно. Высота до auto, а затем сопоставление scrollHeight в том же цикле рендеринга все еще поражает меня, как он «исправляет» эту проблему, хотя технически он должен рисовать только вторую высоту.
Сегодня я попробовал вариант 3 в Chrome, и мне пришлось внести пару настроек. 1) Он не всегда будет правильно уменьшать размер, если у вас есть переход «высота» или «все» в текстовой области. Я бы не рекомендовал использовать переходы, влияющие на высоту. 2) scrollHeight возвращал минимум двух строк в высоту (возможно, потому, что это значение по умолчанию для текстовых полей в Chrome), но если вы измените this.style.height = 'auto'; в this.style.height = '0px'; и добавьте min-height, чтобы предотвратить фактическое изменение начального состояния до 0, scrollHeight будет правильно возвращать одну строку высоты, когда это необходимо.
@ZorroDeLaArena, спасибо, что отметили эти моменты. Вы правы, поведение по умолчанию для многострочного ввода - показывать несколько строк, даже если они пустые, если не указано иное.
@Obsidian Вы можете объяснить, как this.style.height = 'auto'; исправляет поведение scrollHeight? Это просто волшебство.
@sidney Просто: сначала использование auto просто позволяет сбросить высоту текстового поля до высоты верный его содержимого до того, как изменения будут сделаны с помощью scrollheight.
Несколько вещей: я использую первый вариант в модальном окне. На мобильном телефоне он странным образом меняет прокрутку при наборе текста, что раздражает. Во-вторых: кнопки перехода на страницу вверх / вниз не работают с этим скриптом.
@Soaku Пожалуйста, не могли бы вы привести пример, поскольку у меня нет проблем ни с одним из упомянутых вами пунктов, но я хочу, чтобы сценарий был максимально эффективным, поэтому, если есть проблемы, я хотел бы их исправить.
@Obsidian Вы пробовали использовать текстовое поле с текстом, занимающим более 100% высоты экрана? Потом возникает первый глюк,
@Soaku да, jsfiddle.net/n9uuv0hd/94 отлично работает в chrome и работает как домашняя часть textarea в firefox. Можете ли вы придумать свою проблему?
@Obsidian На самом деле ошибка является присутствует в вашей скрипке. Когда я печатаю, прокрутка «телепортируется», поэтому указатель находится прямо в верхней части клавиатуры, когда я нажимаю «ввод», он возвращается в предыдущее положение.
@ZorroDeLaArena Спасибо за ваш вклад. Мне также нужно было отображать 1 строку, когда это необходимо, и this.style.height = '0px' устранил мою проблему.
@Obsidian К сожалению, похоже, из-за this.style.height = 'auto'; переходы CSS по высоте не работают. У меня могут работать переходы и изменение размера при удалении разорванных строк, либо переходы не работают, а изменение размера при удалении строк работает. Какие-нибудь обходные пути?
@sidney Да, мне еще предстоит преодолеть эту трудность. Хотя я обнаружил, что изменение высоты, хотя выглядело хорошо, не было хорошо принято моей клиентской базой. В этом случае скорость важнее стиля!
elem [0] .scrollHeight может помочь в случае, если elem.scrollHeight не работает
Работает ли он в динамически созданном текстовом поле после загрузки документа?
@jjxtra Да, это так!
> Обновлено 05.07.2019 (улучшенная поддержка браузеров для мобильных телефонов и планшетов) Обновлено из будущего!
@PWKad lol Нет, мы сначала используем НОРМАЛЬНЫЕ даты в Англии с наименьшим знаменателем. Дни, месяцы, годы. (Вы бы не стали читать часы Часы / Секунды / Минуты, не так ли?) Человек, которого вы знаете, не должен был делать такое предположение.
@DreamTeK большое спасибо, второй вариант работает как шарм!
Почему мой не работает? В React тоже работает? Я включаю файл main.js в index.html, но он почему-то не работает. Похоже, функция не вызывается
@KittichoteKamalapirat, если вы создадите новый вопрос, показывающий пример вашего текущего кода, я был бы счастлив попытаться помочь вам с этим. На данный момент я бы удостоверился, что jQuery инициализирован до вашего файла main.js. Затем я бы проверил, что весь ваш файл main.js не содержит ошибок, потому что одна пропущенная точка с запятой приведет к сбою в вашем документе.
@DreamTeK Спасибо за ответ. Я добавил сюда вопрос, пожалуйста, проверьте его. Сообщите мне, если предоставленной мной информации недостаточно stackoverflow.com/questions/58008393/…
По какой-то причине мое текстовое поле остается на 0 пикселей при загрузке страницы даже с предварительно загруженным текстом. Я вижу, что он работает в примере jsfiddle (вариант 1), но у меня в приложении точно такой же код, и он не работает. :-( Это работает, когда я печатаю в текстовом поле, но не работает при загрузке страницы.
@Vincent Тогда у вас должен быть другой конфликтующий код в вашем приложении. Скорее всего, это css или Javascript. Попробуйте использовать веб-консоль браузера при запуске приложения, чтобы увидеть, какая высота применяется к текстовому полю.
По-прежнему существует вариант использования, на который не дан ответ в вашем примере: если начальная высота текстового поля не является автоматической? Пустой textarea имеет высоту в два ряда. Если я возьму jsfiddle из вашего второго примера и добавлю начальный style = "height: 33px" в пустое текстовое поле, вы увидите, что ваш код нарушает высоту текстового поля, снова делая его двумя строками ...
@fla Код не ломается, он выполняет то, для чего был запрограммирован. Установка высоты встроенного стиля будет проигнорирована скриптом из-за специфики. Если вам нужна высота по умолчанию для пустого поля, вам нужно будет добавить предостережение в функцию javascript для проверки пустого содержимого, а затем установить начальную высоту по-другому. например, jsfiddle.net/fxre1zm5
Речь идет не о пустом содержимом, а о текстовом поле с одной строкой. Высота текстового поля должна быть высотой содержимого. Если мой контент находится только в одной строке, высота текстового поля должна быть одной строкой, а не двумя.
@fla Вход с type = "textarea" по умолчанию является многострочным, однако вы можете изменить поведение по умолчанию, используя мое предложение. У вас это не сработало?
если у кого-то есть проблемы с начальной высотой текстового поля, просто получите и установите высоту ТОЛЬКО после установки overflow hidden $ el.style ['overflow-y'] = 'hidden'; $ el.style.height = $ el.scrollHeight + 'px';
Это должен быть принятый ответ. Вариант 2 работает как шарм.
Я использовал "чистый javascript". Это действительно хорошо работает и определенно помогло мне. Спасибо! Как ни странно, мне не удалось заставить работать другую версию ответа, поэтому я очень рад, что вы добавили это.
Кто-нибудь считал удовлетворенным? Не нужно возиться с прокруткой, и единственный 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> при вводе.
contenteditable хорош, но если вам нужен открытый текст, ему понадобится множество опций, таких как -webkit-user-modify: read-write-plaintext-only и white-space: pre-wrap.
@_sbaechler: <div> опускаются при использовании [dom-element].innerText. @WebmasterG IMHO было бы неплохо опустить jquery (для прозрачности) и включить пример на этой странице через исполняемый фрагмент кода вместо jsfiddle.
Я не знаю, упоминал ли кто-нибудь об этом, но в некоторых случаях можно изменить высоту с помощью атрибутов строк
textarea.setAttribute('rows',breaks);
Это работает, только если у вас есть white-space: nowrap;. Когда строка переносится на другую строку без разрыва строки, текстовое поле больше не будет правильно настроено.
Вы можете использовать этот код:
Гроб:
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 Похоже, это невозможно из-за дизайна многострочного редактирования. Я сделал пример анимации размера текстового поля: jsfiddle.net/yk2g333e Как вы знаете, текстовый курсор опускается вниз в точке и строки или курсора, поэтому, если в этот момент нет паузы, анимировать нечего. Но пауза будет раздражать пользователя.
@ user2513846 Однако с еще одной пустой строкой в конце textarea можно получить плавную анимацию: jsfiddle.net/p23erdfr
Полезная настройка для этого решения - также скрыть вертикальную полосу прокрутки (видно в jsFiddle, здесь не упоминается), вы делаете это с помощью встроенного стиля (style = "overflow: hidden") или правильного с помощью: textarea {overflow: hidden;}
@Gregor Simončič Да, особенно для длинного текста - он дает правильный расчет целевой высоты текстового поля. Кроме того, для точного расчета лучше установить outerHeight равным 0.
Решение 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 (' Вход' );
Этот код работает для вставки, а также для удаления.
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;
}
это не полное решение.
Я рекомендую библиотеку 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 еще в нескольких случаях:
textarea изменяется с изменением размера окна, или другие события, которые изменяют ширину текстовой областиtextareadisplay изменяется, например когда он переходит с none (скрыт) на blocktextareaОбратите внимание, что использование 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]; это очень плохая практика ... В любом случае решение не подходит для меня, так как мне нужно, чтобы текстовое поле было однострочным, пока не будет больше текста.
Нативное решение 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 Да, но это не одно и то же. Тойота делает красные машины, и Форд тоже делает красные машины, но ведь они разные, не так ли? Если вам больше нравится другой ответ, продолжайте. Но есть те, кто больше ценит мой ответ и согласен с ним. Иметь разные варианты - хорошо.
Кажется, ни один из ответов не работает. Но это работает для меня: 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".
Сделайте 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;});
Лучший способ, который я нашел:
$("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». Если ваш текст длиннее, чем ширина текстового поля, но вы не нажимаете «ввод», он не расширяется.
Я создал небольшой (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;
}
Принятый ответ для темы, которую вы связали, работает для меня. Добавление разрывов строк расширяет текстовое поле, а удаление их сжимает текстовую область. Какой браузер вы используете?