[英]How to auto resize the textarea to fit the content?
我正在嘗試自動調整textarea
的大小以使其適合其中的內容,但是在單擊 Enter 進入下一行后,我遇到了口吃問題。 我怎樣才能解決這個問題?
請參閱此鏈接以獲取 StackBlitz 示例
代碼
this.form.valueChanges.subscribe(() => {
const textarea = this.myDiv.nativeElement;
textarea.addEventListener('keydown', function() {
setTimeout(() => {
this.style.cssText = 'height:auto; padding:0';
this.style.cssText = 'height:' + this.scrollHeight + 'px';
}, 0);
});
});
這里的addEventListener
是多余的,因為valueChanges
已經在字段更改時通知您。 相反,使用ViewChild
引用myDiv
更新高度。
this.myForm.valueChanges.subscribe(value => {
this.myDiv.nativeElement.style.height = 'auto';
this.myDiv.nativeElement.style.height = `${this.myDiv.nativeElement.scrollHeight}px`;
});
然后將overflow: hidden
添加到您的 css 中,這樣滾動條就不會顯示。
textarea {
resize: horizontal;
overflow: hidden;
}
您可以保持resize: horizontal;
但不再需要它,因為 textarea 無論如何都會自動調整大小。
這是StackBlitz上的一個工作示例。
您要達到的目標是一個非常古老的技巧。 我自己使用過它,但嘗試了不同的方法。
更有意義的是,為什么文本區域會跳動,因為您每次擊鍵時都將height = 0
計算為滾動高度,以便您可以分配新的高度。
我計算了 fontSize 或 lineHeight 並計算了行數和基於此調整的初始高度。 因此,在每次擊鍵時,您只需分配高度而不使文本區域高度 = 0
textareaProps = null;
getHeight(element) {
const lines = element.value.split(/\r\n|\r|\n/).length;
if(!this.textareaProps) {
const autoStyle = getComputedStyle(element);
const lineHeight = parseInt(autoStyle.lineHeight);
const adjust = parseInt(autoStyle.height) - lineHeight;
this.textareaProps = {adjust, lineHeight}
}
const { adjust, lineHeight } = this.textareaProps;
const height = lines * lineHeight + adjust;
return height + 'px';
}
您現在需要調用此方法來獲取高度並將 textarea 元素作為 arg 傳遞。
element.style.cssText = 'height:' + getHeight(element) ;
編輯 2
遺憾的是,上述解決方案僅在用戶有換行符時才有效。 當您輸入一個大行文本區域時,它會換行,但不會增加高度。 因此引入了一個代理 html 元素,它將具有與文本區域值相同的文本,並將提供我們可以分配給我們的文本區域的高度。
textareaProps = null;
getHeight(element) {
if(!this.textareaProps) {
const proxy = document.createElement('div');
const {padding, width, fontSize, height, lineHeight} = getComputedStyle(element);
const css = [
'position:absolute',
'visibility: hidden',
'pointer-events:none',
`width: ${width}`,
`padding:${padding}`,
`min-height: ${height}`,
`font-size:${fontSize}`,
`line-height:${lineHeight}`,
].join(';');
proxy.style.cssText=css;
this.textareaProps = {
proxy: document.body.appendChild(proxy),
adjust: (parseInt(fontSize))
};
}
const { proxy, adjust} = this.textareaProps;
proxy.innerText = element.value + '.';
return (proxy.offsetHeight + adjust) + 'px';
}
更新了 StackBlitz https://stackblitz.com/edit/next-line-view-child-ssnp4q
對於幾乎在 2021 年仍在尋找答案的任何人,這里的官方 Angular 材料文檔對此進行了介紹。 通過nativeElement
直接操作 DOM 是一種反模式。
<mat-form-field [style.fontSize]="fontSize.value">
<mat-label>Autosize textarea</mat-label>
<textarea matInput
cdkTextareaAutosize
#autosize="cdkTextareaAutosize"
cdkAutosizeMinRows="1"
cdkAutosizeMaxRows="5"></textarea>
</mat-form-field>
如果您不想要插件,有一個非常簡單的解決方案
$(document).ready(function() {
$('textarea').on('keyup keypress', function() {
$(this).height(0);
$(this).height(this.scrollHeight);
});
$("textarea").each(function(textarea) {
$(this).height(0);
$(this).height(this.scrollHeight);
});
});
<textarea rows="15" id="code" disabled placeholder="Description"></textarea>
rows="15" 將最小高度設置為 15 行
el = document.getElementById("code");
el.style.height = "auto";
// code to populate textarea
el.style.height = (5 + el.scrollHeight) + "px";
這幫助我根據其中填充的內容將 textarea 設置為高度。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.