高度自适应的textarea


本文作者: jsweibo

本文链接: https://jsweibo.github.io/2019/10/25/%E9%AB%98%E5%BA%A6%E8%87%AA%E9%80%82%E5%BA%94%E7%9A%84textarea/

摘要

本文主要讲述了:

  1. 原理

正文

原理

示例:当向<textarea>中输入文本时,<textarea>scrollHeight会随着文本行数的增加而增加

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<meta http-equiv="X-UA-Compatible" content="ie=edge" />
<title>Document</title>
</head>
<body>
<textarea id="foo" placeholder="placeholder"></textarea>
<script>
document.querySelector('#foo').addEventListener('input', function () {
console.log(this.scrollHeight);
});
</script>
</body>
</html>

根据scrollHeightclientHeight的性质可得:

  • scrollHeight >= clientHeight
  • clientHeight = padding-top + content-box-height + padding-bottom
  • content-box-height = height - horizontal-scroll-bar-height

若不会出现水平滚动条,且使padding-toppadding-bottom等于0,则可得:

  • scrollHeight >= clientHeight
  • clientHeight = content-box-height
  • content-box-height = height

即:scrollHeight >= height

综上,只要将scrollHeight实时同步给height即可

示例:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<meta http-equiv="X-UA-Compatible" content="ie=edge" />
<title>Document</title>
</head>
<body>
<textarea id="foo" placeholder="placeholder"></textarea>
<style>
#foo {
padding: 0;
}
</style>
<script>
document.querySelector('#foo').addEventListener('input', function () {
this.style.height = this.scrollHeight + 'px';
});
</script>
</body>
</html>

当文本行数减小时,由于scrollHeight最小值为height,且<textarea>style.height已经被设置成了定值,所以哪怕文本行数减小了,scrollHeight仍将保持不变。

为了解决这个问题,在监听到字符串长度减小时,先将<textarea>style.height设为auto,使得scrollHeight能正常减小,而后再将减小后的scrollHeight赋值给height,从而实现高度自适应。

示例:

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
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<meta http-equiv="X-UA-Compatible" content="ie=edge" />
<title>Document</title>
</head>
<body>
<textarea id="foo" placeholder="placeholder"></textarea>
<style>
#foo {
padding: 0;
}
</style>
<script>
const element = document.querySelector('#foo');
let oldStringLength = element.value.length;
let newStringLength = element.value.length;
element.addEventListener('input', function () {
newStringLength = element.value.length;
if (newStringLength < oldStringLength) {
element.style.height = 'auto';
}
element.style.height = element.scrollHeight + 'px';
oldStringLength = newStringLength;
});
</script>
</body>
</html>

参考资料

本文作者: jsweibo

本文链接: https://jsweibo.github.io/2019/10/25/%E9%AB%98%E5%BA%A6%E8%87%AA%E9%80%82%E5%BA%94%E7%9A%84textarea/


本文对你有帮助?请支持我


支付宝
微信