创建具有自动调整大小的文本区域


366

关于这个另一个线程,我已经试过。但是有一个问题: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

3
我的函数没有错误。必须在行尾键入新行。这是更好的解决方案。 james.padolsey.com/javascript/jquery-plugin-autoresize



如果您使用react,则为此创建了一个程序包:npmjs.com/package/react-fluid-textarea
Martin Dawson

Answers:


230

这对我有效(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,但我希望它只能是纯文本格式。


13
是的!为ya制作了一个jsfiddle:jsfiddle.net/CbqFv它现在可以在Chrome,Firefox和IE8中使用-尽管在IE8中有点故障。当您增加或减少行数时,它会有些奇怪。正如您可能在jQuery的autoresize插件中看到的那样,它们可以通过以下方法解决:克隆textarea,将其高度设置为auto而不是原始高度,然后使用它在原始高度上设置scrollheight。我在更新后的小提琴中这样做:jsfiddle.net/CbqFv/2它解决了IE问题,但Firefox停止工作。
克里斯·莫斯基尼

3
@HelenNeely:然后不要使用id。例如,使用一个类,并对该类的所有元素执行初始化操作。那应该是一个初学者的任务。
panzi 2012年

3
@DenilsonSá如果只能假设只使用现代的浏览器,那么使用Web是更好的地方。
panzi 2012年

2
如果IE11中包含滚动条,这将无法正常工作。如果您使用此小提琴jsfiddle.net/CbqFv并输入行,直到有了滚动条,您将看到它。有任何想法吗?
kaljak

6
如果textarea靠近页面的末尾,这将完全中断-由于出现了一切来回跳动style.height='auto'。我怀疑解决方案是添加一个仅用于测量的隐藏同级。
rr-

372

完整而简单的解决方案

2020年514日更新(改进了对手机和平板电脑的浏览器支持)

以下代码将起作用:

  • 按键输入。
  • 带有粘贴的文本(右键单击和Ctrl + v)。
  • 带有剪切文字(右键单击和Ctrl + x)。
  • 带有预加载的文本。
  • 在所有textarea (多行文本框)站点范围内。
  • 使用Firefox (已通过v31-67测试)。
  • 使用Chrome (已测试v37-74)。
  • 使用IE (已测试v9-v11)。
  • 使用Edge (已测试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');

预设TEXTAREA高度

要固定文本区域的初始高度,您需要添加其他条件:

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>


12
这是一个很好的解决方案,如果将方法名称和参数名称更新为真实名称而不是单个字母,则可能会更容易理解。
克里斯·马里西奇

5
@黑曜石谢谢!我只是想出了为什么总是得到0的原因-我将textarea放在了Bootstrap模式中!由于模态在第一隐藏,文本区域在它会有一个0 scrollHeight属性😂😂
WTIFS

7
@黑曜石太棒了!! (选项3)。这this.style.height = 'auto';是魔术行为修复。我很沮丧,为什么scrollHeight在行为上如此怪异。自动将其设置为高度,然后在同一渲染周期中匹配scrollHeight,这仍然使我震惊,尽管它在技术上仅应该绘画第二个高度,但它如何“修复”此问题。
位少

2
我今天在Chrome浏览器中尝试了选项3,并且不得不进行一些调整。1)如果您在文本区域上进行了“高度”或“全部”过渡,则无法始终正确缩小尺寸。我建议不要使用影响高度的过渡。2)scrollHeight返回的最小值是两行高度(也许因为这是Chrome中textareas的默认值),但是如果您更改this.style.height ='auto'; 到this.style.height ='0px'; 并添加一个min-height以防止初始状态实际变为0,scrollHeight将在适当的时候正确返回一行高度。
ZorroDeLaArena

3
@Obsidian您能解释一下如何this.style.height = 'auto';解决scrollHeight的行为吗?这只是魔术。
悉尼,

63

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/


5
这很好,但是我会添加overflow-y: hidden;到CSS来防止在调整大小时滚动条短暂地闪烁。
brettjonesdev

不能完全确定,但是没有它,文本区域会增加太多。我认为这与元素scrollHeight的计算方式有关。
2013年

1
使用多个事件为广泛的场景做好准备 $('textarea.auto-resize').on('change cut paste drop keyup', function(){...})
raxith 2014年

1
在比视口更长的文本上,在Chrome 40 Win 8.1中像疯了似的跳来跳去。使其非常不可用。
tobibeer 2015年

1
按住Enter键(换行符)将导致滚动。释放钥匙之前,尺寸不会调整。
Niels Abildgaard 2015年

28
<!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更好

Edit:在使用前声明函数Edit:input比keydown更好(thnx @ WASD42&@ MA-Maddin)

jsfiddle


3
这有一些缺点:1)不会调整Textarea的大小,而是仅用鼠标按钮粘贴某些内容;2)如果用户使用键盘(Ctrl + V)粘贴某些内容,则只有在释放Ctrl时,文本区域才会被调整大小。如果用户多次按Ctrl + V,则文本区域仅在最后一个文本区域之后才会增长。您还应该添加相同的功能来粘贴,剪切,更改和放置事件。
2013年

因此,只需使用input事件即可。参见stackoverflow.com/a/14029861/1951524
Martin Schneider 2016年

改进的版本具有textareadocument.querySelectorAll('textarea').forEach(function(te){ te.addEventListener("input", function() { this.style.height='24px'; this.style.height=this.scrollHeight+12+'px'; }); });
单线

1
@Meisner它更短,但我不会说它是“改进的”。使用匿名功能,无法调用removeEventListener和清理事件侦听器。在forEach循环中各处创建事件侦听器时,这一点尤其重要。另外,在我看来,可读性比简洁要重要得多。
GijsjanB

对于其他人和将来的我,请确保box-sizing: border-box;已设置属性,否则对于每个onInput事件,textarea会增加4px。我花了大约3个小时才弄清楚这是问题所在。
AIon

24

对我来说最好的解决方案(可行且简短)是:

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

它就像一个饰物一样工作,没有粘贴(也可以用鼠标)闪烁,剪切,进入,并且缩小到合适的大小。

请看看jsFiddle


了不起!!!一线成交!愚蠢的问题ho我可以在调整大小时添加动画吗?像文本框sorta轻轻地调整大小,而不是跳转到大小?
user2513846 '16

1
@ user2513846看来通过多行编辑的设计是不可能的。我举了一个为textarea大小设置动画的示例:jsfiddle.net/yk2g333e如您所知,文本光标在line或插入符号的和处落下,因此,如果此时没有暂停,则无需进行动画处理。但是暂停将使用户烦恼。
vatavale

1
@ user2513846但是,在textarea的末尾再有一个空行,则可以实现平滑的动画:jsfiddle.net/p23erdfr
vatavale

16

您正在使用当前clientHeight和内容scrollHeight中的较高值。当您通过删除内容来减小scrollHeight时,由于先前由style.height设置的clientHeight将其保持打开状态,因此无法减小计算区域。取而代之的是,您可以采用max()的scrollHeight和您已预定义或从textarea.rows计算出的最小高度值。

通常,您可能不应该真正依赖表单控件上的scrollHeight。除了传统上对scrollHeight的支持程度低于其他某些IE扩展之外,HTML / CSS并没有说明如何在内部实现表单控件,并且不能保证scrollHeight会有意义。(传统上,某些浏览器使用OS窗口小部件来完成该任务,从而使CSS和DOM在其内部的交互成为不可能。)在尝试启用效果之前,至少要嗅探一下scrollHeight / clientHeight的存在。

如果在更广泛的范围内工作很重要,则可以避免该问题的另一种可能的替代方法可能是使用隐藏的div,其大小与文本区域的宽度相同,并设置为相同的字体。在键入时,您将文本从文本区域复制到隐藏div中的文本节点(请记住用换行符替换'\ n',如果使用innerHTML,请正确转义'<'/'&')。然后只需测量div的offsetHeight就可以为您提供所需的高度。


1
哪些浏览器应该存在scrollHeight文本区域问题?在当前版本的IE,Firefox和Opera上运行良好...
Christoph

1
我唯一需要处理的是Konqueror,它将clientHeight返回为scrollHeight。除非浏览器将CSS框模型应用于小部件的内部,否则这种行为是您可以预期的,这并不是它们经常执行的操作,并且标准没有说必须这样做。
bobince

14

如果您不需要支持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 Ill resize.</textarea>

您可以在我的博客文章中了解有关其工作原理的更多信息


1
不错的解决方案,但几乎不需要修复。加载textarea的内容时,执行f.ex。从数据库来看,textarea保持很小。您必须input在foreach周期的初始化期间触发事件。
阿贾克斯

11

自动尺寸

https://github.com/jackmoore/autosize

可以独立运行的Just作品很受欢迎(截至2018年10月,已有3,000个 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 Cloud 9编辑器中内容的高度


2
第2版​​已于2015年2月发布。它变得更加简单,不再依赖jQuery
酥脆的

抱歉,确实可以。也许我是在其他浏览..所以,我认为这是更好,如果你无视我的意见..
托尼·米歇尔Caubet

@ToniMichelCaubet啊,好吧,也许是CDN问题。我检查一下
Ciro Santilli郝海东冠状病六四事件法轮功

autosize插件不允许使用textarea中的调整大小图标手动调整大小。
j4v1

7

这里找到一个班轮;

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

6

有人认为内容可编辑吗?不用乱搞滚动,并且我唯一喜欢的JS是如果您打算以模糊方式保存数据...显然,它与所有流行的浏览器兼容:http : //caniuse.com/#feat =内容可编辑

只需将其设置为看起来像文本框的样式,然后它就会自动调整大小...将其最小高度设置为首选的文本高度并具有该高度。

这种方法最酷的是,您可以在某些浏览器上进行保存和标记。

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

<style>
.autoheight {
    min-height: 16px;
    font-size: 16px;
    margin: 0;
    padding: 10px;
    font-family: Arial;
    line-height: 16px;
    box-sizing: border-box;
    -moz-box-sizing: border-box;
    -webkit-box-sizing: border-box;
    overflow: hidden;
    resize: none;
    border: 1px solid #ccc;
    outline: none;
    width: 200px;
}
</style>
<script src="https://code.jquery.com/jquery-2.1.1.min.js"></script>
<script>
$(document).on('blur','.autoheight',function(e) {
    var $this = $(this);
    // The text is here. Do whatever you want with it.
    console.log($this.html());
});

</script>
<div class="autoheight contenteditable" contenteditable="true">Mickey Mouse</div>

Chrome会在ENTER上添加<div>元素。
sbaechler,2016年

contenteditable很好,但是如果您想使用纯文本,则需要一堆选项,例如-webkit-user-modify: read-write-plaintext-onlywhite-space: pre-wrap
mik01aj

@_sbaechler:使用时将省略<div> [dom-element].innerText。@WebmasterG恕我直言,最好省略jquery(为透明起见),并通过可运行的代码片段而不是jsfiddle将此示例包含在此页面上。
adabru '18年

4

我将以下代码用于多个文本区域。即使在textarea中执行删除,剪切和粘贴操作,在Chrome 12,Firefox 5和IE 9中也可以正常工作。

<!-- language: lang-html -->
<style type='text/css'>
textarea { border:0 none; overflow:hidden; outline:none; background-color:#eee }
</style>
<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>
<script type='text/javascript'>
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
</script>

4

有一种稍微不同的方法。

<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


1
只要确保pre字体大小与textarea ”相同--他们就需要相同的字号line-height,并且padding和/或数量border也相等。这是Angular的最佳解决方案。
Jamie Barker

4

以下内容适用于剪切,粘贴等操作,无论这些操作是否来自鼠标,键盘快捷键,从菜单栏中选择一个选项...几个答案采用类似的方法,但它们并没有说明大小调整,这就是为什么他们错误地应用样式的原因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. textareadisplaystyle属性更改时,例如,它从none(隐藏)变为block
  3. 当值 textarea编程方式更改

请注意,使用window.getComputedStyle或获取currentStyle可能在计算上有些昂贵,因此您可能需要缓存结果。

适用于IE6,所以我真的希望有足够的支持。


4

作为另一种方法,您可以使用<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

@adabru是的,但是两个答案不一样。丰田制造红色汽车,福特也制造红色汽车,但是它们是不同的,不是吗?如果您更喜欢其他答案,请选择它。但是,有些人更欣赏我的回答并接受它。有不同的选择是好的。
Racil Hilan

3

进行一些更正。在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;
  });

只要您的行不会溢出,它们就可以工作-那么它们将不合适。
托马斯·卡夫卡

开箱即用,很棒(firefox 72)
Mikeys4u

2

我知道用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>

jQuery的.live()已被弃用。api.jquery.com/live您通常会想.on()改用。
路加福音

2

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

textarea.setAttribute('rows',breaks);

演示版


1
那只有在你有的情况下才有效white-space: nowrap;。当一行换行到另一行而没有换行符时,textarea将不再正确调整。
雪人

2

这是panzi答案的angularjs指令。

 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]; 这是一个非常糟糕的习惯...无论如何,该解决方案对我来说没有好处,因为我需要textarea为一行,直到有更多文本为止。
Karol Websky '17

2

您可以使用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,

2

那些想要在新版本的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';
    }
  }

1

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

假设您不想通过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);

1

一个更简单,更干净的方法是:

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

1

此代码适用于粘贴,也可以选择删除。

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


1

我建议从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)
}

1

使用qQuery的MakeTextAreaResisable

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


1

我的实现非常简单,计算输入中的行数(最少2行以表明这是一个文本区域):

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

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

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


2
仅当您通过按“ enter”来换行时才有效。如果文本的长度大于文本区域的宽度,但未单击“ enter”,则文本不会扩展。
Nathalia Xavier

1

接受的答案工作正常。但这是用于此简单功能的大量代码。下面的代码可以解决问题。

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

0

这是我将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上进行了测试


0

您可以使用以下代码:

咖啡:

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

Java脚本

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();
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.