前言
类似微信聊天输入框,输入框高度跟随输入内容变化而变化。
具体方案
方案一:隐藏div自动撑高
-
将
textarea
外面套一个容器box,同时在这个box中放入一个隐藏的div(visibility:hidden
) -
监听
textarea
的输入事件并将其中的文本动态的同步到div中,这样div 就可以撑开容器box -
由于div的高度和文本框的高度一致,那么
textarea
的高度自然就是其中文字内容的高度了。 -
div和textarea需要设置相同的
padding
,和相同的行号line-height
,相同的字体,否则高度不同步。
vue示例代码:
<template>
<div class="reason-box">
<!-- 作为背景隐藏,内容自动撑高 -->
<div v-if="autoHeightTextarea" class="bg-txt-area">{{ inputReasonText }}</div>
<textarea
v-model="inputReasonText"
class="reason-textarea auto-height-textarea"
:class="{'': auto}"
:placeholder="placeHolder"
:maxlength="inputMaxLength"
@input="input"
@keyup="input"
></textarea>
<div class="reason-number">{{ inputReasonText.length }}/{{ inputMaxLength }}</div>
</div>
</template>
<script>
export default {
name: 'Textarea',
props: {
// 输入内容的最大字符长度
inputMaxLength: {
type: Number,
default: 200
},
// 输入内容的提示信息
placeHolder: {
type: String,
default: '提示信息'
},
// 输入框高度跟随内容自动变化
autoHeightTextarea: {
type: Boolean,
default: false
}
},
data() {
return {
// 输入的内容
inputReasonText: ''
}
},
methods: {
input(e) {
const val = e.target.value || '';
this.$emit('changeContent', { inputReasonText: val });
}
}
}
</script>
<style lang="stylus" scoped>
.reason-box
position: relative;
border-radius: 0.08rem;
margin: 0.16rem .32rem 0 .32rem;
background: #f2f3f8;
padding: 0.16rem 0.24rem;
.reason-textarea
min-height: 1.74rem;
padding-bottom: 0.28rem;
caret-color: #d2001c;
display block;
width 100%;
overflow scroll;
border none;
font-size .28rem;
color #0A0F16;
&::placeholder
color rgba(10, 15, 22, 0.4);
.reason-number
position: absolute;
bottom: 0.16rem;
right: 0.24rem;
font-size: 0.28rem;
color: rgba(10, 15, 22, 0.2);
.bg-txt-area
visibility hidden;
font-size .28rem;
padding-bottom: 0.28rem;
min-height 2.05rem;
white-space: pre-wrap;
word-break: break-word;
.auto-height-textarea
position absolute;
top 0;
left 0;
overflow: hidden;
resize none;
padding 0.16rem 0.24rem;
height: 100%;
</style>
注意点:
white-space: pre-wrap 保证浏览器渲染div内容时保留空白和换行符序列。
word-break: break-word保证textarea自动换行能同步给div。
@keyup="input"保证输入回车也能同步给div,让div自动撑开高度。
方案二:通过js检测文本的高度,然后动态设置文本框的高度。
具体思路:当出现滚动条的时候,文本的实际高度就是**scrollHeight**
,我们只需要设置文本框的高度为内容的**scrollHeight**
即可。
示例:
<!DOCTYPE html>
<html lang="en">
<head>
<title>demo1</title>
<style>
textarea {
width: 200px;
min-height: 100px;
padding: 0;
}
</style>
</head>
<body>
<textarea placeholder="input..."></textarea>
</body>
<script>
var textarea = document.querySelector('textarea');
textarea.addEventListener('input', (e) => {
textarea.style.height = '100px';
textarea.style.height = e.target.scrollHeight + 'px';
});
</script>
</html>
注意点:
-
由于textarea默认是有padding 的,所以在设置文本框高度的时候要减去padding*2
-
需要在每次设置scrollHeight之前,设置一次文本框的初始高度
textarea.style.height = '100px';
,这样在文本内容减少的时候,文本框的高度才会减少。