使用自动调整大小创建textarea

Dis*_*oat 328 html javascript height textarea resize

还有另外一个关于这个问题,我试过了.但是有一个问题: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 )
    };
}
Run Code Online (Sandbox Code Playgroud)

Dre*_*TeK 312

完整的简单解决方案

更新时间23/08/2017 (改进了对手机和平板电脑的浏览器支持)

以下代码将起作用:

  • 关键输入.
  • 使用粘贴文本(右键单击&ctrl + v).
  • 使用剪切文本(右键单击&ctrl + x).
  • 使用预加载的文本.
  • 所有textarea (多行文本框)都在网站范围内.
  • 使用Firefox (v31-55测试).
  • 使用Chrome (v36-60测试).
  • IE (v9-v11测试).
  • 使用Edge (v14-v15测试).
  • 使用IOS Safari.
  • 使用Android浏览器.
  • 使用JavaScript 严格模式.
  • 是否验证了w3c.
  • 并且简化和高效.

选项1 (使用jQuery)

此代码需要jQuery并且已经过测试,并且正在使用1.7.2 - 3.2.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';
});
Run Code Online (Sandbox Code Playgroud)
<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>
Run Code Online (Sandbox Code Playgroud)

Test on jsfiddle


选项2 (纯JavaScript)

简单 (将此JavaScript添加到主脚本文件中并忘记它.)

var tx = document.getElementsByTagName('textarea');
for (var 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';
}
Run Code Online (Sandbox Code Playgroud)
<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>
Run Code Online (Sandbox Code Playgroud)

Test on jsfiddle


选项3 (jQuery扩展)

如果您想要进一步链接到想要自动调整大小的textareas,这很有用.

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);
      });
    });
  }
});
Run Code Online (Sandbox Code Playgroud)

调用 $('textarea').autoHeight()


通过JAVASCRIPT更新TEXTAREA

通过JavaScript将内容注入textarea时,请附加以下代码以调用选项1中的函数.

$('textarea').trigger('input');
Run Code Online (Sandbox Code Playgroud)

  • 这是一个很好的解决方案,如果将方法名称和参数名称更新为真实名称而不是单个字母,则会更容易理解. (12认同)
  • @Obsidian太棒了!! (备选方案3).`this.style.height ='auto';`是神奇的行为修正.我很沮丧为什么scrollHeight的行为如此奇怪.auto的高度,然后在同一个渲染周期中匹配scrollHeight仍然让我想到它是如何'修复'这个问题虽然它应该只是技术上绘制第二个高度. (7认同)
  • @Obsidian谢谢!我只知道为什么我总是得到0 - 我把textarea放在Bootstrap模态中!由于模态最初是隐藏的,因此其中的textarea将具有0 scrollHeight (5认同)
  • 我今天在Chrome中尝试了选项3,并且不得不进行一些调整.1)如果在textarea上有"高度"或"全部"转换,它将不会总是正确调整大小.我建议不要使用影响高度的过渡.2)scrollHeight返回了两行高度的最小值(也许是因为这是Chrome中textareas的默认值)但是如果你改变了this.style.height ='auto'; to this.style.height ='0px'; 并添加一个最小高度以防止初始状态实际变为0,scrollHeight将在适当时正确返回一行高度. (2认同)
  • @Obsidian你能解释一下`this.style.height ='auto';`修复了scrollHeight的行为吗?这真是太神奇了. (2认同)
  • @sidney Simply:首先使用 `auto` 只允许在使用 `scrollheight` 进行更改之前将 textarea 的高度重置为其内容的**正确**高度。 (2认同)
  • 如果有人对文本区域的初始高度有疑问,只需在设置溢出隐藏后获取并设置高度 $el.style['overflow-y'] = 'hidden'; $el.style.height = $el.scrollHeight + 'px'; (2认同)
  • 这应该是公认的答案。选项 2 很有魅力。 (2认同)
  • 通过设置 `rows="1"` 可以将一行文本的高度减少到一行。另外,请注意任何直接操纵文本区域的高度来计算最终高度的答案(包括这个):当前版本的 iOS Safari 有一个错误,当您在高文本中输入换行符时,滚动会不稳定地上下跳跃。 textarea,因为它尝试将 textarea 保留在视图中。您可以使用不可见的第二个文本区域进行计算来解决此问题。还要考虑由页面尺寸变化等引起的宽度变化可能会影响理想高度。 (2认同)

pan*_*nzi 210

这对我有用(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();
}
Run Code Online (Sandbox Code Playgroud)
textarea {
    border: 0 none white;
    overflow: hidden;
    padding: 0;
    outline: none;
    background-color: #D0D0D0;
}
Run Code Online (Sandbox Code Playgroud)
<body onload="init();">
<textarea rows="1" style="height:1em;" id="text"></textarea>
</body>
Run Code Online (Sandbox Code Playgroud)

如果你想在jsfiddle上尝试它从一行 开始,只增长所需的确切数量.对于一个人来说这是好的textarea,但我想写一些东西,其中我会有许多这样的textareas(大约在一个大文本文档中通常有一行).在那种情况下,它真的很慢.(在Firefox中,它非常慢.)所以我真的想要一种使用纯CSS的方法.这是可能的contenteditable,但我希望它只是纯文本.

  • 它确实!为你做了一个jsfiddle:http://jsfiddle.net/CbqFv/它现在可以在Chrome,Firefox和IE8中运行 - 虽然它在IE8中有点小故障.随着你增加或减少行数,它会变得有点怪异.正如您在jQuery的autoresize插件中看到的那样,他们通过克隆textarea来解决这个问题,将其高度设置为auto而不是原始高度,然后使用它来设置原始的scrollheight.我在这个更新的小提琴中做到了这一点:http://jsfiddle.net/CbqFv/2/它解决了IE问题,但Firefox停止工作. (12认同)
  • 如果textarea靠近底页末端,则会完全中断 - 由于`style.height ='auto'`,所有内容都会前后跳跃.我怀疑解决方案是添加一个仅用于测量的隐藏兄弟. (6认同)
  • @HelenNeely:那就不要使用id.例如,使用一个类并执行init对该类的所有元素执行的操作.那应该是初学者的任务. (3认同)
  • @DenilsonSá如果人们只能假设只使用现代浏览器,那么网络将是一个更好的地方. (3认同)
  • 如果在IE11中包含滚动条,这将无法正常工作.如果你使用这个小提琴http://jsfiddle.net/CbqFv/并输入行,直到你有一个滚动条,你会看到它.有任何想法吗? (2认同)

chi*_*him 63

jQuery解决方案调整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 */
}
Run Code Online (Sandbox Code Playgroud)

JavaScript的...

// auto adjust the height of
$('#container').delegate( 'textarea', 'keydown', function (){
    $(this).height( 0 );
    $(this).height( this.scrollHeight );
});
$('#container').find( 'textarea' ).keydown();
Run Code Online (Sandbox Code Playgroud)

或jQuery 1.7 +的替代品......

// auto adjust the height of
$('#container').on( 'keyup', 'textarea', function (){
    $(this).height( 0 );
    $(this).height( this.scrollHeight );
});
$('#container').find( 'textarea' ).keyup();
Run Code Online (Sandbox Code Playgroud)

我创造了一个小提琴,绝对最小的造型作为你的实验的起点...... http://jsfiddle.net/53eAy/951/

  • 这很好,但我会在css中添加`overflow-y:hidden;`以防止滚动条在调整大小时短暂闪烁. (5认同)
  • 在 Chrome 40 Win 8.1 中,在长于视口的文本上疯狂地跳跃。使其完全无法使用。 (2认同)

Gij*_*anB 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>
Run Code Online (Sandbox Code Playgroud)

在Firefox 14和Chromium 18中测试过.数字24和12是任意的,测试看看哪种最适合你.

你可以没有样式和脚本标签,但它变得有点混乱imho(这是旧式HTML + JS,不鼓励).

<textarea style="overflow: hidden" onkeyup="this.style.height='24px'; this.style.height = this.scrollHeight + 12 + 'px';"></textarea>
Run Code Online (Sandbox Code Playgroud)

编辑:现代化的代码.将onkeyup属性更改为addEventListener.
编辑:KEYDOWN作品比KEYUP更好
编辑:使用前声明函数
编辑:输入作品比的keydown更好(日Thnx @ WASD42&@ MA-Maddin)

的jsfiddle

  • 这个有一些缺点:1)Textarea不会调整大小,然后用户只用他的鼠标按钮粘贴东西; 2)如果用户将使用键盘(Ctrl + V)粘贴某些内容,则仅当他将释放Ctrl时才会调整textarea的大小.如果用户多次按Ctrl + V,则textarea将仅在最后一个之后增长.您应该添加相同的功能来粘贴,剪切,更改和删除事件. (3认同)
  • 对于其他人和未来的我,请确保设置了 `box-sizing: border-box;` 属性,否则每个 onInput 事件的 textarea 都会扩展 4px。我花了大约 3 个小时才发现问题所在。 (2认同)

vat*_*ale 23

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

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

它的作用就像一个没有任何眨眼粘贴的魅力(也带有鼠标),切割,进入并缩小到合适的尺寸.

请看看jsFiddle.


bob*_*nce 16

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

通常,您可能不应该真正依赖于表单控件上的scrollHeight.除了传统上不受广泛支持的scrollHeight之外,HTML/CSS没有说明内部如何实现表单控件,并且不保证scrollHeight将是有意义的.(传统上一些浏览器使用OS小部件来完成任务,使得内部的CSS和DOM交互变得不可能.)在尝试启用效果之前,至少要嗅探scrollHeight/clientHeight的存在.

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


Max*_*ann 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));
}
Run Code Online (Sandbox Code Playgroud)

现在你只需要添加一些CSS就可以了:

textarea[autoresize] {
  display: block;
  overflow: hidden;
  resize: none;
}
Run Code Online (Sandbox Code Playgroud)

用法:

<textarea autoresize>Type here and I’ll resize.</textarea>
Run Code Online (Sandbox Code Playgroud)

您可以在我的博客文章中详细了解它的工作原理.


小智 12

这里找到了一个班轮;

<textarea name="text" oninput="this.style.height = ''; this.style.height = this.scrollHeight +'px'"></textarea>
Run Code Online (Sandbox Code Playgroud)


Cir*_*四事件 11

自动尺寸

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>
Run Code Online (Sandbox Code Playgroud)

顺便说一句,如果您使用ACE编辑器,请使用maxLines: Infinity:在Ace Cloud 9编辑器中自动调整高度到内容

  • 版本2已于2015年2月发布.它已变得更简单,不再依赖于jQuery (2认同)

Web*_*r G 6

有没有人认为满足?没有搞乱滚动,而且我喜欢它的唯一JS就是你打算在模糊上保存数据......显然,它在所有流行的浏览器上兼容:http://caniuse.com/#feat = CONTENTEDITABLE

只需将其设置为文本框样式,然后自动调整...使其最小高度成为首选文本高度并具有此高度.

这种方法的优点在于您可以在某些浏览器上保存和标记.

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>
Run Code Online (Sandbox Code Playgroud)


Jos*_*lds 6

以下适用于剪切、粘贴等,无论这些操作是否来自鼠标、键盘快捷键、从菜单栏中选择选项......几个答案采用类似的方法,但它们没有考虑框 -尺寸,这就是他们错误地应用样式的原因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));
Run Code Online (Sandbox Code Playgroud)
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;
}
Run Code Online (Sandbox Code Playgroud)
<textarea rows="3" id="ta">
Try adding several lines to this.
</textarea>
Run Code Online (Sandbox Code Playgroud)

为了绝对完整,您应该adjust在更多情况下调用该函数:

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

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

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


Rac*_*lan 6

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

div {
  width: 200px;
}

span {
  border: 1px solid #000;
  padding: 5px;
}
Run Code Online (Sandbox Code Playgroud)
<div>
  <span contenteditable="true">This text can be edited by the user</span>
</div>
Run Code Online (Sandbox Code Playgroud)

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


Nik*_*att 5

我将以下代码用于多个文本区域。即使在文本区域中执行删除、剪切和粘贴操作,在 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
Run Code Online (Sandbox Code Playgroud)
textarea {
  border: 0 none;
  overflow: hidden;
  outline: none;
  background-color: #eee
}
Run Code Online (Sandbox Code Playgroud)
<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>
Run Code Online (Sandbox Code Playgroud)


Kar*_*elė 5

有一种稍微不同的方法。

<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>
Run Code Online (Sandbox Code Playgroud)

这个想法是将文本从 复制textareapre并让 CSS 确保它们具有相同的大小。

好处是框架提供了简单的工具来移动文本而不触及任何事件。也就是说,在AngularJS你想补充ng-model="foo" ng-trim="false"textarea,并ng-bind="foo + '\n'"pre。看到一个小提琴

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


Ric*_*las 5

使用 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} />;
Run Code Online (Sandbox Code Playgroud)