还有另一个关于这个的帖子,我试过了。但有一个问题:如果你删除内容,文本区域不会缩小。我找不到任何方法将其缩小到正确的大小- 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 )
    };
}

当前回答

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

其他回答

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

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

窗口调整大小事件(如果文本区域的宽度随着窗口调整大小而改变),或者其他改变文本区域宽度的事件 当文本区域的显示样式属性发生变化时,例如当它从none(隐藏)变为block时 当文本区域的值以编程方式更改时

注意使用window。getComputedStyle或getcurrentstyle在计算上可能有点昂贵,所以您可能想要缓存结果。

适用于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>

作为一种不同的方法,您可以使用<span>来自动调整它的大小。你需要通过添加contentteditable ="true"属性使其可编辑,这样就完成了:

div { 宽度:200 px; } 跨度{ 边框:1px实心#000; 填充:5 px; } < div > <span contenteditable="true">此文本可以由用户编辑</span> < / div >

这种方法的唯一问题是,如果希望将值作为表单的一部分提交,就必须自己用JavaScript完成。这样做相对容易。例如,您可以添加一个隐藏字段,并在表单的onsubmit事件中将span的值赋给隐藏字段,然后该隐藏字段将自动与表单一起提交。

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

textarea.setAttribute('rows',breaks);

Demo