还有另一个关于这个的帖子,我试过了。但有一个问题:如果你删除内容,文本区域不会缩小。我找不到任何方法将其缩小到正确的大小- 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 )
};
}
这是一种基于行的方法,允许您为文本区域设置最大行数,之后文本区域将显示滚动条。除了以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>
你可以使用下面的代码:
Coffescript:
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();
您正在使用当前clientHeight和内容scrollHeight的较高值。当您通过删除内容使scrollHeight变小时,计算区域不能变小,因为先前根据样式设置的clientHeight。高度,是撑开它。您可以使用scrollHeight的max()和预定义的或从textarea.rows中计算的最小高度值。
In general you probably shouldn't really rely on scrollHeight on form controls. Apart from scrollHeight being traditionally less widely-supported than some of the other IE extensions, HTML/CSS says nothing about how form controls are implemented internally and you aren't guaranteed scrollHeight will be anything meaningful. (Traditionally some browsers have used OS widgets for the task, making CSS and DOM interaction on their internals impossible.) At least sniff for scrollHeight/clientHeight's existance before trying to enable the effect.
另一种可能的替代方法来避免这个问题,如果重要的是,它可以更广泛地工作,可能是使用一个隐藏的div大小相同的文本区域的宽度,并设置在相同的字体。在keyup上,您将文本从文本区域复制到隐藏div中的文本节点(记住用换行符替换'\n',如果使用innerHTML则正确转义'<'/'&')。然后简单地测量div的offsetHeight将给你你需要的高度。
对于那些正在寻找特定角度的答案的人,你可以使用这个选项来设置默认行数。
create directive
@Directive({
selector: '[appTextAreaAutoHeight]'
})
export class TextAreaAutoHeightDirective implements AfterViewInit {
private row = 1;
constructor(private el: ElementRef) {
this.row = el.nativeElement.rows;
}
ngAfterViewInit(): void {
const elem = this.el.nativeElement;
elem.style.height = "1px";
elem.style.minHeight = (this.row * elem.scrollHeight) + "px";
}
@HostListener('input', ['$event.target'])
onInput(elem: any) {
elem.style.height = "1px";
elem.style.height = (elem.scrollHeight) + "px";
}
}
使用方法:
<textarea id="title" rows="3" class="col-12 p-1 fs-15 fw-reg
rounded-1" appTextAreaAutoHeight
placeholder="...*******$$$"></textarea>