446

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

47 回答 47

529

完整而简单的解决方案

2020-05-14 更新(改进了对手机和平板电脑的浏览器支持)

以下代码将起作用:

  • 关于按键输入。
  • 粘贴文本(右键单击和 ctrl+v)。
  • 带有剪切文本(右键单击和 ctrl+x)。
  • 带有预加载的文本。
  • 在站点范围内使用所有文本区域(多行文本框) 。
  • 使用Firefox (经过 v31-67 测试)。
  • 使用Chrome (经过 v37-74 测试)。
  • 使用IE (经过 v9-v11 测试)。
  • 使用Edge (经过 v14-v18 测试)。
  • IOS Safari
  • 使用安卓浏览器
  • 使用 JavaScript严格模式
  • 是否经过w3c验证。
  • 并且是精简和高效的。

选项 1 (使用 jQuery)

此选项需要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 = "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>

于 2014-09-02T10:31:56.000 回答
270

这对我有用(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上试试 它从一行开始,只增长必要的确切数量。单个 s 是可以的textarea,但我想写一些我会有很多很多这样textarea的 s 的东西(大约和一个通常在大文本文档中的行一样多)。在那种情况下,它真的很慢。(在 Firefox 中它非常慢。)所以我真的想要一种使用纯 CSS 的方法。这将是可能的contenteditable,但我希望它是纯文本的。

于 2011-03-18T00:21:52.737 回答
68

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/

于 2011-12-15T15:14:41.223 回答
33
<!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 更好
编辑:在使用之前声明函数
编辑:输入比 keydown 更好(thnx @WASD42 & @MA-Maddin)

jsfiddle

于 2012-07-24T09:48:57.747 回答
30

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

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

它就像一个魅力,没有任何粘贴(也有鼠标)闪烁,剪切,进入并缩小到合适的大小。

请看一下jsFiddle

于 2015-12-29T14:49:51.607 回答
17

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

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

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

于 2009-01-18T00:52:10.690 回答
17

从这里找到一个班轮;

<textarea name="text" oninput="this.style.height = ''; this.style.height = this.scrollHeight +'px'"></textarea>
于 2019-12-30T08:06:10.373 回答
15

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

你可以在我的博客文章中阅读更多关于它是如何工作的。

于 2014-07-25T14:27:49.997 回答
14

自动尺寸

https://github.com/jackmoore/autosize

Just works,独立,很受欢迎(截至 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 Cloud 9 编辑器中的内容

于 2014-08-29T10:57:54.033 回答
7

有没有人认为contenteditable?不要乱用滚动,我唯一喜欢它的 JS 是如果你打算将数据保存在模糊上......显然,它在所有流行的浏览器上都兼容:http: //caniuse.com/#feat =内容可编辑

只需将其设置为看起来像一个文本框,然后它会自动调整大小......使其最小高度成为首选文本高度并拥有它。

这种方法的好处在于您可以在某些浏览器上保存和标记。

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>

于 2014-10-16T20:09:28.197 回答
7

作为另一种方法,您可以使用 a<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隐藏字段,然后该隐藏字段将与表单一起自动提交。

于 2018-03-24T14:40:25.030 回答
6

有一种稍微不同的方法。

<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"textareang-bind="foo + '\n'"中添加一个pre. 见小提琴

只要确保它pre的字体大小与textarea.

于 2014-07-17T14:45:33.107 回答
5

我将以下代码用于多个文本区域。在 Chrome 12、Firefox 5 和 IE 9 中运行良好,即使在 textareas 中执行删除、剪切和粘贴操作也是如此。

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>

于 2011-06-23T15:10:50.767 回答
5

以下适用于剪切,粘贴等,无论这些操作是否来自鼠标,键盘快捷键,从菜单栏中选择一个选项......几个答案采用类似的方法,但它们不考虑框 -调整大小,这就是他们错误地应用样式的原因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,所以我真的希望这是足够好的支持。

于 2017-05-01T03:01:27.787 回答
4

一点修正。在 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;
  });
于 2011-06-19T12:14:03.347 回答
4

这是 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>
于 2017-08-29T20:08:53.933 回答
3

我知道用 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>
于 2012-05-24T08:46:12.153 回答
3

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

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

于 2014-07-31T20:58:47.517 回答
3

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

textarea.setAttribute('rows',breaks);

演示

于 2014-11-11T12:48:45.453 回答
3

textarea您可以在键入时使用 JQuery 来扩展:

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

于 2018-11-28T00:10:22.797 回答
3

那些想在新版本的 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';
    }
  }
于 2019-04-15T16:52:19.150 回答
2

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

假设您有一个不想超过的 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);
于 2013-06-01T12:51:00.000 回答
2

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

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

于 2016-09-12T06:01:30.047 回答
2

我推荐来自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)
}
于 2017-03-01T08:59:10.937 回答
2

似乎没有一个答案有效。但这对我有用: 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();
于 2018-05-23T08:45:12.567 回答
2

使用 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();
}
于 2018-06-19T18:01:48.073 回答
2

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

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

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

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

于 2019-05-09T15:55:52.747 回答
2

接受的答案工作正常。但这对于这个简单的功能来说是很多代码。下面的代码可以解决问题。

   $(document).on("keypress", "textarea", function (e) {
    var height = $(this).css("height");
    var iScrollHeight = $(this).prop("scrollHeight");
    $(this).css('height',iScrollHeight);
    });
于 2020-03-05T13:46:21.627 回答
1

如果可以信任 scrollHeight ,那么:

textarea.onkeyup=function() {
  this.style.height='';
  this.rows=this.value.split('\n').length;
  this.style.height=this.scrollHeight+'px';
}
于 2010-10-01T23:34:18.743 回答
1

这是我在使用 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 上测试过

于 2013-09-11T13:38:19.977 回答
0

对于那些希望 textarea 在宽度和高度上自动调整大小的人:

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

代码笔:

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

干杯,

于 2015-06-29T04:51:34.800 回答
0

jQuery 解决方案是将 textarea 的高度设置为“auto”,检查 scrollHeight,然后在每次 textarea 更改(JSFiddle)时调整 textarea 的高度:

$('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 中测试和工作。还支持剪切粘贴、长字等。

于 2016-07-02T10:15:28.773 回答
0

只需<pre> </pre>与一些样式一起使用,例如:

    pre {
        font-family: Arial, Helvetica, sans-serif;
        white-space: pre-wrap;
        word-wrap: break-word;
        font-size: 12px;
        line-height: 16px;
    }
于 2016-09-30T07:42:01.643 回答
0

您可以使用这段代码来计算 textarea 需要的行数:

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

计算它inputwindow:resize事件以获得自动调整大小的效果。Angular 中的示例:

模板代码:

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

自动换行.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;
  }

}
于 2017-03-14T13:22:14.460 回答
0

本机 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,包括内部文本和测量高度。

于 2017-11-18T05:49:56.627 回答
0

我发现的最好方法:

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

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

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

于 2019-01-17T17:47:24.973 回答
0

我创建了一个小的 (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

于 2019-11-15T12:03:17.850 回答
0

这是Moussawi7答案的jQuery 版本。

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

于 2020-08-16T00:04:43.523 回答
0

我知道我参加这个聚会迟到了,但我遇到的最简单的解决方案是将文本区域内容拆分为换行符并更新 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>
于 2020-09-25T18:05:56.213 回答
0

对于 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;
}
于 2020-10-06T14:18:02.990 回答
0

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

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

此版本的一个缺点是它将继续根据文本宽度无限增加其宽度。因此,您需要max-widthtextarea. 一个简单max-width: 100%;的也可以解决问题。此宽度扩展功能主要基于input. type="text"您可以在此答案中阅读更多相关信息。

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>

于 2021-07-13T05:59:39.760 回答
0

使用 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>

于 2021-08-03T15:36:33.797 回答
0

这里有一个明确的答案:

退格键增加滚动高度的值

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

于 2022-01-01T12:28:44.003 回答
-1

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

我已经使用 jQuery 应用了 DisgruntledGoat 脚本并添加了 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);
}
于 2009-09-07T14:01:05.413 回答
-1
$('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');
});
于 2011-02-17T10:14:52.190 回答
-1

我可以使用以下 jQuery 函数在 IE9 和 Chrome 中设置 TextArea 大小。它从 $(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我的文本区域的字符限制在哪里。这将与文本大小允许的一样大(基于您的字符数和字体大小)。当您从文本区域中删除字符或用户最初粘贴太多文本时,它也会适当地缩小您的文本区域。

于 2012-05-09T21:57:49.503 回答
-1

您可以使用以下代码:

咖啡稿:

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();
于 2015-06-08T15:03:49.470 回答