有another thread about this,我试过。但是有一个问题:如果删除内容,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 )
};
}
这对我有用(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
s(大约一个通常在大型文本文档中有行)。在那种情况下,它真的很慢。 (在Firefox中,它非常慢。)所以我真的想要一种使用纯CSS的方法。这可能与contenteditable
,但我希望它只是纯文本。
我将以下代码用于多个textareas。在Chrome 12,Firefox 5和IE 9中正常工作,即使在textareas中执行删除,剪切和粘贴操作。
<!-- 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>
有一种略有不同的方法。
<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
。看到fiddle。
只需确保pre
具有与textarea
相同的字体大小。
以下适用于剪切,粘贴等,无论这些操作是来自鼠标,键盘快捷键,从菜单栏中选择一个选项......几个答案采取类似的方法,但他们不考虑框 - 大小,这就是为什么他们错误地应用风格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
函数:
textarea
的宽度随窗口大小调整而改变,或其他更改textarea宽度的事件,则窗口调整大小事件textarea
的display
样式属性发生变化时,例如当它从none
(隐藏)到block
textarea
的值时请注意,使用window.getComputedStyle
或获取currentStyle
可能在某种程度上计算成本很高,因此您可能希望缓存结果。
适用于IE6,所以我真的希望得到足够的支持。
作为一种不同的方法,您可以使用<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
的值分配给隐藏字段,然后将随表单自动提交。
一点修正。在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;
});
我知道用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>
这是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>
您可以在键入时使用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>
这里的一些答案不考虑填充。
假设你有一个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);
更新日期07/05/2019(改进了对手机和平板电脑的浏览器支持)
以下代码将起作用:
此选项需要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>
简单(将此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';
}
<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>
如果您想要进一步链接到想要自动调整大小的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);
});
});
}
});
用$('textarea').autoHeight()
调用
通过JavaScript将内容注入textarea时,请附加以下代码以调用选项1中的函数。
$('textarea').trigger('input');
这是一个更简单,更清洁的方法:
// 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
此代码也适用于粘贴和选择删除。
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
只需使用<pre> </pre>
,如:
pre {
font-family: Arial, Helvetica, sans-serif;
white-space: pre-wrap;
word-wrap: break-word;
font-size: 12px;
line-height: 16px;
}
那些想要在新版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';
}
}
我的实现非常简单,计算输入中的行数(最少2行表示它是textarea):
textarea.rows = Math.max(2, textarea.value.split("\n").length) // # oninput
充满活力的刺激示例:https://jsbin.com/kajosolini/1/edit?html,js,output
(这适用于浏览器的手动调整大小句柄)
这是我在为TextArea使用MVC HTML Helper时所做的。我有很多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上测试过它
您可以使用此代码:
CoffeeScript的:
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();
对于那些希望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 )
}
})
Codepen:
http://codepen.io/anon/pen/yNpvJJ
干杯,
jQuery解决方案是将textarea的高度设置为'auto',检查scrollHeight,然后每次textarea更改时调整textarea的高度(JSFiddle):
$('textarea').on( 'input', function(){
$(this).height( 'auto' ).height( this.scrollHeight );
});
如果您正在动态添加textareas(通过AJAX或其他),您可以在$(document).ready中添加它,以确保所有带有'autoheight'类的textareas保持与其内容相同的高度:
$(document).on( 'input', 'textarea.autoheight', function() {
$(this).height( 'auto' ).height( this.scrollHeight );
});
在Chrome,Firefox,Opera和IE中经过测试和使用。还支持剪切和粘贴,长字等。
您可以使用这段代码来计算textarea所需的行数:
textarea.rows = 1;
if (textarea.scrollHeight > textarea.clientHeight)
textarea.rows = textarea.scrollHeight / textarea.clientHeight;
在input
和window:resize
事件上计算它以获得自动调整大小的效果。 Angular中的示例:
模板代码:
<textarea rows="1" reAutoWrap></textarea>
自动wrap.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;
}
}
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 */
}
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/
原生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上测试过。
此解决方案创建类似于textarea的div,包括内部文本和度量高度。
<!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是任意的,测试看看哪种最适合你。
你可以没有样式和脚本标签,但它变得有点混乱imho(这是旧式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)
对我来说,最好的解决方案(有效且简短)是:
$(document).on('input', 'textarea', function () {
$(this).outerHeight(38).outerHeight(this.scrollHeight); // 38 or '1em' -min-height
});
它的作用就像一个没有任何眨眼粘贴的魅力(也带有鼠标),切割,进入并缩小到合适的尺寸。
请看看jsFiddle。
您正在使用当前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将为您提供所需的高度。
如果您不需要支持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>
你可以阅读更多关于它是如何工作的on my blog post。
自动尺寸
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>
顺便说一句,如果您使用ACE编辑器,请使用maxLines: Infinity
:Automatically adjust height to contents in Ace Cloud 9 editor
有没有人认为满足?没有搞乱滚动,并且我喜欢它的唯一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>