还有另一个关于这个的帖子,我试过了。但有一个问题:如果你删除内容,文本区域不会缩小。我找不到任何方法将其缩小到正确的大小- clientHeight值返回为文本区域的完整大小,而不是它的内容。

该页面的代码如下:

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

当前回答

还有一种略有不同的方法。

<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相同。

其他回答

如果scrollHeight可以信任,那么:

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

jQuery的解决方案是设置文本区域的高度为'auto',检查scrollHeight,然后调整文本区域的高度,每次文本区域改变(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。还支持剪切和粘贴,长字等。

我在常见的浏览器中测试了脚本,在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);
}

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

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

下面的代码将工作:

按键输入。 粘贴文本(右键单击并ctrl+v)。 剪切文本(右键单击并ctrl+x)。 与预加载文本。 与所有的文本区域(多行文本框的)网站宽。 使用Firefox (v31-109测试)。 Chrome (v37-108测试)。 使用IE (v9-v11测试)。 使用Edge (v14-v108测试)。 IOS Safari。 Android浏览器。 JavaScript严格模式。


选项1(使用jQuery)

此选项需要jQuery,并且已经过测试,适用于1.7.2 - 3.6.3

简单(将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://ajax.aspnetcdn.com/ajax/jQuery/jquery-3.6.3.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上测试


OPTION 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 = 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 (jQuery扩展)

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

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>

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