JavaScript 中 textarea 自适应高度

Posted by cl9000 on May 20, 2020

创造性就是发明、实验、成长、冒险、犯规、犯错和享受乐趣。 ——<玛丽·卢·库克>

原文链接:https://bdadam.com/blog/automatically-adapting-the-height-textarea.html

简介

textareas有一个大问题:默认情况下,textareas具有固定的高度。您可以设置rows属性以告知应显示多少行,也可以设置其style.height属性。但不幸的是,没有自动高度属性。

实现思路

每次更改文本后,我们都必须测量内容的高度。幸运的是有一种方法可以做到这一点。element.scrollHeight不管可见的滚动条如何,都能为我们提供内容的高度。为了减小大小,我们每次将高度设置回零,以便scrollHeight报告所需的最小值而不是更多。例如,当用户删除一行时。

我们还必须计算边框和轮廓的大小,以便我们不给任何机会截断内容或显示滚动条。

然后,将style.height属性设置为计算出的高度。

为了每次都执行此操作,我们使用oninput事件,每次文本内容更改时都会触发该事件。相反onchange,仅当用户单击时才触发。

实现代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
<textarea data-adaptheight rows="3" cols="40" placeholder="您的输入" style="padding: 16px; line-height: 1.5;"></textarea>
<script>
(function() {
function adjustHeight(textareaElement, minHeight) {
// compute the height difference which is caused by border and outline
var outerHeight = parseInt(window.getComputedStyle(el).height, 10);
var diff = outerHeight - el.clientHeight;

// set the height to 0 in case of it has to be shrinked
el.style.height = 0;

// set the correct height
// el.scrollHeight is the full height of the content, not just the visible part
el.style.height = Math.max(minHeight, el.scrollHeight + diff) + 'px';
}


// we use the "data-adaptheight" attribute as a marker
var textAreas = [].slice.call(document.querySelectorAll('textarea[data-adaptheight]'));

// iterate through all the textareas on the page
textAreas.forEach(function(el) {

// we need box-sizing: border-box, if the textarea has padding
el.style.boxSizing = el.style.mozBoxSizing = 'border-box';

// we don't need any scrollbars, do we? :)
el.style.overflowY = 'hidden';

// the minimum height initiated through the "rows" attribute
var minHeight = el.scrollHeight;

el.addEventListener('input', function() {
adjustHeight(el, minHeight);
});

// we have to readjust when window size changes (e.g. orientation change)
window.addEventListener('resize', function() {
adjustHeight(el, minHeight);
});

// we adjust height to the initial content
adjustHeight(el, minHeight);

});
}());
</script>

实现演示

总结

每次按键都会导致重画。因为我们将文本区域的高度设置为0,然后设置为计算值。
但是,这应该可以忽略不计,因为大多数用户每秒最多只能键入几个字符。因此,它不会引起任何明显的性能缺陷。

用处

在许多情况下,这可能是有用的。在其他人中:

  • 文字编辑器
  • 代码编辑器
  • 评论框

参考

关注【公众号】,了解更多。



支付宝打赏 微信打赏

赞赏一下 坚持原创技术分享,您的支持将鼓励我继续创作!