创建一个自动调整大小的文本区域

另一个关于这个的帖子,我试过了。但有一个问题:如果你删除内容,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 )
};
}
616410 次浏览

您正在使用当前clientHeight和内容scrollHeight的较高值。当您通过删除内容使scrollHeight变小时,计算区域不能变小,因为先前根据样式设置的clientHeight。高度,是撑开它。您可以使用scrollHeight的max()和预定义的或从textarea.rows中计算的最小高度值。

一般来说,你可能不应该在表单控件上依赖scrollHeight。除了scrollHeight传统上不像其他一些IE扩展那么广泛支持,HTML/CSS没有说表单控件是如何内部实现的,你不能保证scrollHeight将是任何有意义的东西。(传统上,一些浏览器使用OS小部件来完成任务,使得CSS和DOM无法在其内部进行交互。)在尝试启用该效果之前,至少嗅嗅scrollHeight/clientHeight的存在。

另一种可能的替代方法来避免这个问题,如果重要的是,它可以更广泛地工作,可能是使用一个隐藏的div大小相同的文本区域的宽度,并设置在相同的字体。在keyup上,您将文本从文本区域复制到隐藏div中的文本节点(记住用换行符替换'\n',如果使用innerHTML则正确转义'<'/'&')。然后简单地测量div的offsetHeight将给你你需要的高度。

我在常见的浏览器中测试了脚本,在Chrome和Safari中失败了。这是因为不断更新的scrollHeight变量。

我已经使用jQuery应用了wrettledgoat脚本,并添加了chrome修复

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';
}
$('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,但我希望它是纯文本

稍微更正一下。完美演绎歌剧

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

< p > 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/ < / p >

我能够设置TextArea大小在IE9和Chrome与下面的jQuery函数。它绑定到$(document).ready()函数中定义的选择器中的textarea对象。

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>
<!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是任意的,测试一下看看哪个最适合你。

你可以不使用样式和脚本标记,但这会变得有点混乱(这是老式的HTML+JS,不鼓励使用)。

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

编辑:现代化代码。修改onkeyup属性为addEventListener.
编辑:keydown工作比keyup
更好 编辑:在使用
之前声明函数 编辑:输入工作比键下(thnx @WASD42 &@MA-Maddin) < / p >

jsfiddle

这里的一些答案没有考虑到填充。

假设你有一个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 for TextArea时所做的。我有相当多的textarea元素,所以必须使用模型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中,你可以在textarea中添加ng-model="foo" ng-trim="false",在pre中添加ng-bind="foo + '\n'"。见小提琴

只要确保pre的字体大小与textarea相同即可。

如果你不需要支持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>

你可以阅读更多关于它如何工作< a href = " https://max。Hn /thoughts/autoresizing-textareas" rel="nofollow noreferrer">在我的博客文章

一个更简单、更清晰的方法是:

// 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

autosize

https://github.com/jackmoore/autosize

只是作品,独立,很受欢迎(截至2018年10月,3.0k+ GitHub星),可在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云9编辑器

一个完整而简单的解决方案

更新<强> 2022-08-30 (默认增加了单行多文本框的支持)

下面的代码将工作:

  • 按键输入。
  • 使用粘贴文本(右键点击&ctrl + v)。
  • 与剪切文本(右键点击&ctrl + x)。
  • 与预加载文本。
  • 所有textarea的(多行文本框)站点宽。
  • 使用火狐 (v31 - 67)进行测试。
  • 使用 (v37 - 74)进行测试。
  • 使用 (v9-v11测试)。
  • 使用边缘 (v14-v18测试)。
  • IOS狩猎
  • Android浏览器
  • 使用JavaScript 严格模式
  • 验证了w3c
  • 并且精简高效。

选项1 __abc0

此选项需要jQuery,并已经过测试,正在使用1.7.2 - 3.6

简单的 (将jquery代码添加到主脚本文件中,然后忘记它。)

$("textarea").each(function () {
this.setAttribute("style", "height:" + (this.scrollHeight) + "px;overflow-y:hidden;");
}).on("input", function () {
this.style.height = 0;
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>

jsfiddle上的测试


选项2 __abc0

简单的 (将此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 = 0;
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>

jsfiddle上的测试


选项3 __abc0

如果你想应用进一步的链接到文本区域,你想自动大小有用。

jQuery.fn.extend({
autoHeight: function () {
function autoHeight_(element) {
return jQuery(element)
.css({ "height": 0, "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 = 0;
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>

有人觉得满意吗?没有混乱的滚动,和唯一的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.log(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>

我不知道是否有人提到这种方式,但在某些情况下,可以用rows属性调整高度

textarea.setAttribute('rows',breaks);

Demo

你可以使用下面的代码:

Coffescript:

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.log($(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:

< a href = " http://codepen。io /不久/钢笔/ yNpvJJ " rel = " http://codepen.io/anon/pen/yNpvJJ nofollow”> < / >

欢呼,

对我来说,最好的解决方案(既有效又简短)是:

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

它的工作就像一个魅力没有任何闪烁的粘贴(与鼠标也),切割,进入,它缩小到正确的大小。

请看jsFiddle

jQuery的解决方案是设置textarea的高度为'auto',检查scrollHeight,然后调整textarea的高度,每次textarea改变(JSFiddle):

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

如果你在动态添加文本区域(通过AJAX或其他方式),你可以在$(document)中添加这个。准备好确保所有带有类'autoheight'的文本区域保持与它们的内容相同的高度:

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

测试和工作在Chrome, Firefox, Opera和IE。还支持剪切和粘贴,长字等。

这段代码也适用于粘贴和选择删除。

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>

Here is the JSFiddle

只需要使用<pre> </pre>的一些样式,比如:

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

我推荐使用http://javierjulio.github.io/textarea-autosize中的javascript库。

每个注释,添加插件使用的示例代码块:

<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需要的行数:

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

inputwindow: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;
}


}

下面的工作用于剪切,粘贴等,不管这些操作是来自鼠标,键盘快捷键,从菜单栏选择一个选项…有几个答案采用了类似的方法,但它们没有考虑box-sizing,这就是为什么它们错误地应用了overflow: hidden样式。

我执行以下操作,这也适用于max-heightrows的最小高度和最大高度。

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>

本地Javascript解决方案没有闪烁在Firefox和更快的方法与clientheight…

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的值赋给隐藏字段,然后该隐藏字段将自动与表单一起提交。

这些答案似乎都不管用。但这个对我很有用: https://coderwall.com/p/imkqoq/resize-textarea-to-fit-content < / p >

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

MakeTextAreaResisable使用qQuery

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>

我发现最好的方法是:

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

其他方法有一个字体大小的错误。

这就是为什么这是最好的。

那些想要在Angular的新版本中实现同样功能的人。

抓取textArea element。

@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):

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

刺激的完整工作示例:https://jsbin.com/kajosolini/1/edit?html,js,output

(这适用于浏览器的手动调整大小句柄,例如)

我创建了一个小的(7kb)自定义元素来处理所有这些调整大小的逻辑。

它可以在任何地方工作,因为它是作为自定义元素实现的。包括:虚拟dom (React, Elm等),服务器端呈现的东西,如PHP和简单乏味的HTML文件。

除了监听输入事件外,它还有一个计时器,每100毫秒触发一次,以确保在文本内容通过其他方式发生变化的情况下,事情仍在工作。

下面是它的工作原理:

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

或作为脚本标记包含

<script src="//cdn.jsdelivr.net/npm/autoheight-textarea@1.0.1/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版本的Moussawi7回答

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

这是一种基于行的方法,允许你为textarea设置最大行数,之后textarea将显示滚动条。除了以rows属性的形式调整其高度外,它还将在键入或执行剪切和粘贴等操作时自动扩展其宽度。

如果textarea除了占位符没有任何内容,它将根据占位符文本调整其宽度和高度。

这个版本的一个缺点是,它将继续无限增加它的宽度基于文本宽度。因此,你需要将max-width值设置为textarea。简单的max-width: 100%;也可以做到。这个宽度扩展特性主要基于type="text"input字段。你可以在这个回答中阅读更多关于它的信息。

const textarea = document.querySelector('textarea');


setTextareaWidthHeight(textarea);
textarea.addEventListener('input', setTextareaWidthHeight.bind(this, textarea));


function getInputWidth(element) {
const text = element.value || element.placeholder;
const elementStyle = window.getComputedStyle(element);
const fontProperty = elementStyle.font;
const horizontalBorder = parseFloat(elementStyle.borderLeftWidth) + parseFloat(elementStyle.borderRightWidth);
const horizontalPadding = parseFloat(elementStyle.paddingLeft) + parseFloat(elementStyle.paddingRight);


const canvas = document.createElement('canvas');
const context = canvas.getContext('2d');
context.font = fontProperty;
const textWidth = context.measureText(text).width;


const totalWidth = horizontalBorder + horizontalPadding + textWidth + "px";
return totalWidth;
}


function setTextareaWidthHeight(element) {
// store minimum and maximum rows attribute value that should be imposed
const minRows = 1;
const maxRows = 5;


// store initial inline overflow property value in a variable for later reverting to original condition
const initialInlineOverflowY = element.style.overflowY;


// change overflow-y property value to hidden to overcome inconsistent width differences caused by any scrollbar width
element.style.overflowY = 'hidden';


const totalWidth = getInputWidth(element);
element.style.width = totalWidth;


let rows = minRows;
element.setAttribute("rows", rows);


while (rows <= maxRows && element.scrollHeight !== element.clientHeight) {
element.setAttribute("rows", rows);
rows++;
}


// change overflow to its original condition
if (initialInlineOverflowY) {
element.style.overflowY = initialInlineOverflowY;
} else {
element.style.removeProperty("overflow-y");
}
}
textarea {
max-width: 100%;
}
<textarea placeholder="Lorem ipsum dolor sit amet"></textarea>

React的一个示例实现:

const {
useLayoutEffect,
useState,
useRef
} = React;


const TextArea = () => {
const ref = useRef();
const [value, setValue] = useState('Some initial text that both wraps and uses\nnew\nlines');


// This only tracks the auto-sized height so we can tell if the user has manually resized
const autoHeight = useRef();


useLayoutEffect(() => {
if (!ref.current) {
return;
}


if (
autoHeight.current !== undefined &&
ref.current.style.height !== autoHeight.current
) {
// don't auto size if the user has manually changed the height
return;
}


ref.current.style.height = "auto";
ref.current.style.overflow = "hidden";
const next = `${ref.current.scrollHeight}px`;
ref.current.style.height = next;
autoHeight.current = next;
ref.current.style.overflow = "auto";
}, [value, ref, autoHeight]);




return (
<textarea
ref={ref}
style=\{\{
resize: 'vertical',
minHeight: '1em',
}}
value={value}
onChange={event => setValue(event.target.value)}
/>
);
}


ReactDOM.render(<TextArea />, document.getElementById('app'))
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/17.0.1/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/17.0.1/umd/react-dom.production.min.js"></script>
<div id="app"></div>

这里有一个明确的答案:

backspace增加scrollheight的值

它使用现代ES6语法,解决了添加或删除内容时精确调整大小的问题。它解决了滚动高度值不断变化的问题。

一个使用React的简单方法。

...
const textareaRef = useRef();


const handleChange = (e) => {
textareaRef.current.style.height = "auto";
textareaRef.current.style.height = textareaRef.current.scrollHeight + "px";
};


return <textarea ref={textareaRef} onChange={handleChange} />;

改进的响应式纯JS解决方案,以@DreamTeK的第二个选项为基础

下面还处理了底部填充以及窗口大小的调整。像这样,这对我来说是一个近乎完美的解决方案。非常感谢他。

let textareas = document.getElementsByClassName("auto-resize-textarea");


// Loop through textareas and add event listeners as well as other needed css attributes
for (const textarea of textareas) {
// Initially set height as otherwise the textarea is not high enough on load
textarea.style.height = textarea.scrollHeight.toString();
// Hide scrollbar
textarea.style.overflowY = 'hidden';
// Call resize function with "this" context once during initialisation as it's too high otherwise
resizeTextarea.call(textarea);
// Add event listener to resize textarea on input
textarea.addEventListener('input', resizeTextarea, false);
// Also resize textarea on window resize event binding textarea to be "this"
window.addEventListener('resize', resizeTextarea.bind(textarea), false);
}
function resizeTextarea() {
// Textareas have default 2px padding and if not set it returns 0px
let padding = window.getComputedStyle(this).getPropertyValue('padding-bottom');
// getPropertyValue('padding-bottom') returns "px" at the end it needs to be removed to be added to scrollHeight
padding = parseInt(padding.replace('px',''));
this.style.height = "auto";
this.style.height = (this.scrollHeight) + "px";
}
textarea {
width:40%;
padding:20px 25px;
border-radius: 20px;
}
<textarea class="auto-resize-textarea">Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua.</textarea>
<textarea placeholder="Type, paste, cut text here..." class="auto-resize-textarea"></textarea>

请注意:有一个奇怪的问题与jsfiddle的文本区域太高,底部有太多的空间,但复制和粘贴这个确切的代码到一个空的html文件完美地工作。

有一个小问题,但当滚动条出现在页面和文本区域收缩和包装文本,并创建一个新的行。上面的函数没有考虑到这一点,我提出一个问题,但似乎没有人知道一个修复。如果你有解决这个问题的建议,我将非常高兴。

对于那些正在寻找特定角度的答案的人,你可以使用这个选项来设置默认行数。

create directive


@Directive({
selector: '[appTextAreaAutoHeight]'
})
export class TextAreaAutoHeightDirective implements AfterViewInit {
private row = 1;
constructor(private el: ElementRef) {
this.row = el.nativeElement.rows;
}
ngAfterViewInit(): void {
const elem = this.el.nativeElement;
elem.style.height = "1px";
elem.style.minHeight = (this.row * elem.scrollHeight) + "px";
}


@HostListener('input', ['$event.target'])
onInput(elem: any) {
elem.style.height = "1px";
elem.style.height = (elem.scrollHeight) + "px";
}
}

使用方法:

<textarea id="title" rows="3" class="col-12 p-1 fs-15 fw-reg
rounded-1" appTextAreaAutoHeight
placeholder="...*******$$$"></textarea>