高度自适应输入框

3,335 阅读2分钟

最近有个需求做一个高度自适应的输入框,就这点东西找一个依赖不划算,就简单手撸一个。

掘金搜了一下资料,都是几年前的。基于大佬的这篇文章  [贝聊科技]不简单的自适应高度输入框 上做一下细微调整就行。

对比其他方案的优势

1. 使用 textarea

2. 不需要js

3. 回车跳一下问题解决

大佬的解决方案

1. `contenteditable`直接排除,肯定是要用 textarea 实现,属性那么多不可能再自己去做一遍。

3. textarea的scrollHeight也排除,功能不复杂就不要用JS,看反馈好像还有比较多问题。

所以用的方案2,套一层就能解决问题(代码折叠一行了,不知道怎么弄,截个图)

<!DOCTYPE html><html lang="en"><head>  <meta charset="UTF-8">  <meta name="viewport" content="width=device-width, initial-scale=1.0">  <title>Document</title>  <style>    .a-textarea {      position: relative;      border: 1px solid red;    }    .textarea,    .hidden-box {      padding: 12px;      margin: 0;      font-family: Arial, Helvetica, sans-serif;      font-size: 16px;      line-height: 28px;      outline: 0;      white-space: pre-wrap;      word-wrap: break-word;      word-break: break-all;    }    .textarea {      position: absolute;      inset: 0;      resize: none;      border: none;    }    .hidden-box {      visibility: hidden;    }  </style>  <script src="https://unpkg.com/vue@3/dist/vue.global.js"></script></head><body>  <div id="app">    <div class="a-textarea"> <textarea v-model="message" class="textarea"></textarea>      <pre class="hidden-box">{{message}}</pre>    </div>  </div>  <script>    const { createApp, ref } = Vue;    createApp({      setup() {        const message = ref('高度自适应输入框')        return { message }      }    })      .mount('#app')    </script></body></html>

功能是实现了,但是应该都发现了一个问题,回车之后会跳一下,这是因为末尾是回车没有内容导致高度没有,输入内容之后有高度会导致跳一下。大佬原文 “如果换行符刚好在内容的末尾,那么在容器中的换行并不会生效,这时候需要在换行符后面补上一个空格(或者其他非空白字符)”,然后大佬的解决方案是这个,也不是不行,但用到js还是麻烦。

$textarea.addEventListener('input', function(e) {
   $text.innerText = e.target.value.replace(/\n$/, '\n '); // 解决不换行问题
});

解决方案 “在换行符后面补上一个空格”,都写到这了,“:after”这么好用没人想到,还是css写的少了。(ps:'​ '为零宽字符)

.hidden-box::after {  content: '&#8203;';}

完整代码

<html lang="en"><head>  <meta charset="UTF-8">  <meta name="viewport" content="width=device-width, initial-scale=1.0">  <title>Document</title>  <style>    .a-textarea {      position: relative;      border: 1px solid red;    }    .textarea,    .hidden-box {      padding: 12px;      margin: 0;      font-family: Arial, Helvetica, sans-serif;      font-size: 16px;      line-height: 28px;      outline: 0;      white-space: pre-wrap;      word-wrap: break-word;      word-break: break-all;    }

有人说没有效果的,突然想起掘金有编辑器,直接看效果吧

源码

bugs:

0. 肥猪大大 提的 超长文本会出现滚动条修改;(给.textarea加一个overflow: hidden;去除滚动条)

1. 英文单词换行错误。删除word-break: break-all;