还有另一个关于这个的帖子,我试过了。但有一个问题:如果你删除内容,文本区域不会缩小。我找不到任何方法将其缩小到正确的大小- 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 )
};
}
你可以使用这段代码来计算一个textarea需要的行数:
textarea.rows = 1;
if (textarea.scrollHeight > textarea.clientHeight)
textarea.rows = textarea.scrollHeight / textarea.clientHeight;
在输入和窗口:resize事件上计算它以获得自动调整大小的效果。Angular中的例子:
模板代码:
<textarea rows="1" reAutoWrap></textarea>
auto-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;
}
}
一个更简单、更清晰的方法是:
// 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类添加到您想要的目标文本区域。
在FF, Chrome和Safari测试。如果这对你不起作用,请告诉我,不管是什么原因。但是,这是我发现的最简单明了的方法。而且效果非常好!: D
这是一种基于行的方法,允许您为文本区域设置最大行数,之后文本区域将显示滚动条。除了以rows属性的形式调整它的高度之外,它还会在键入或执行剪切和粘贴之类的操作时自动扩展它的宽度。
如果文本区域没有任何内容,只有一个占位符,它将根据占位符文本调整其宽度和高度。
这个版本的一个缺点是,它将继续无限增加它的宽度基于文本宽度。因此,你需要为文本区域设置一个max-width值。简单的max-width: 100%;也会有效果。这个宽度扩展特性主要基于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>
你可以使用这段代码来计算一个textarea需要的行数:
textarea.rows = 1;
if (textarea.scrollHeight > textarea.clientHeight)
textarea.rows = textarea.scrollHeight / textarea.clientHeight;
在输入和窗口:resize事件上计算它以获得自动调整大小的效果。Angular中的例子:
模板代码:
<textarea rows="1" reAutoWrap></textarea>
auto-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;
}
}
本地Javascript解决方案没有闪烁在Firefox和更快的方法与clientheight…
1)将div.textarea selector添加到所有包含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类似于您的文本区域,包括内部文本和测量高度。