textarea高度自适应

25 阅读1分钟

前言

      类似微信聊天输入框,输入框高度跟随输入内容变化而变化。

具体方案

方案一:隐藏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';,这样在文本内容减少的时候,文本框的高度才会减少。

参考:

textarea内容自动撑开高度,实现高度自适应

小程序/网页实现textarea高度随内容自动改变